diff options
162 files changed, 4926 insertions, 6110 deletions
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 7cca1b6f2a..748d787b86 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -169,10 +169,12 @@ /modules/gridmap/icons/ @godotengine/3d-nodes @godotengine/usability /modules/noise/ @godotengine/core /modules/noise/doc_classes/ @godotengine/core @godotengine/documentation +/modules/noise/icons/ @godotengine/core @godotengine/usability /modules/noise/tests/ @godotengine/core @godotengine/tests /modules/regex/ @godotengine/core /modules/regex/doc_classes/ @godotengine/core @godotengine/documentation -/modules/regex/test/ @godotengine/core @godotengine/tests +/modules/regex/icons/ @godotengine/core @godotengine/usability +/modules/regex/tests/ @godotengine/core @godotengine/tests /modules/zip/ @godotengine/core /modules/zip/doc_classes/ @godotengine/core @godotengine/documentation @@ -207,6 +209,7 @@ /scene/resources/text_paragraph.* @godotengine/gui-nodes /scene/resources/visual_shader*.* @godotengine/shaders /scene/theme/ @godotengine/gui-nodes +/scene/theme/icons/ @godotengine/gui-nodes @godotengine/usability # Servers diff --git a/.github/workflows/runner.yml b/.github/workflows/runner.yml index d2d0e3571f..fd5e74b914 100644 --- a/.github/workflows/runner.yml +++ b/.github/workflows/runner.yml @@ -1,5 +1,5 @@ name: 🔗 GHA -on: [push, pull_request] +on: [push, pull_request, merge_group] concurrency: group: ci-${{ github.actor }}-${{ github.head_ref || github.run_number }}-${{ github.ref }}-runner diff --git a/SConstruct b/SConstruct index 5566770148..63cff4fe16 100644 --- a/SConstruct +++ b/SConstruct @@ -299,7 +299,6 @@ opts.Add(BoolVariable("builtin_pcre2_with_jit", "Use JIT compiler for the built- opts.Add(BoolVariable("builtin_recastnavigation", "Use the built-in Recast navigation library", True)) opts.Add(BoolVariable("builtin_rvo2_2d", "Use the built-in RVO2 2D library", True)) opts.Add(BoolVariable("builtin_rvo2_3d", "Use the built-in RVO2 3D library", True)) -opts.Add(BoolVariable("builtin_squish", "Use the built-in squish library", True)) opts.Add(BoolVariable("builtin_xatlas", "Use the built-in xatlas library", True)) opts.Add(BoolVariable("builtin_zlib", "Use the built-in zlib library", True)) opts.Add(BoolVariable("builtin_zstd", "Use the built-in Zstd library", True)) @@ -640,25 +639,18 @@ if env.dev_build: print("NOTE: Developer build, with debug optimization level and debug symbols (unless overridden).") # Enforce our minimal compiler version requirements -cc_version = methods.get_compiler_version(env) or { - "major": None, - "minor": None, - "patch": None, - "metadata1": None, - "metadata2": None, - "date": None, -} -cc_version_major = int(cc_version["major"] or -1) -cc_version_minor = int(cc_version["minor"] or -1) -cc_version_metadata1 = cc_version["metadata1"] or "" - -if methods.using_gcc(env): - if cc_version_major == -1: - print_warning( - "Couldn't detect compiler version, skipping version checks. " - "Build may fail if the compiler doesn't support C++17 fully." - ) - elif cc_version_major < 9: +cc_version = methods.get_compiler_version(env) +cc_version_major = cc_version["major"] +cc_version_minor = cc_version["minor"] +cc_version_metadata1 = cc_version["metadata1"] + +if cc_version_major == -1: + print_warning( + "Couldn't detect compiler version, skipping version checks. " + "Build may fail if the compiler doesn't support C++17 fully." + ) +elif methods.using_gcc(env): + if cc_version_major < 9: print_error( "Detected GCC version older than 9, which does not fully support " "C++17, or has bugs when compiling Godot. Supported versions are 9 " @@ -678,17 +670,12 @@ if methods.using_gcc(env): print_warning("GCC < 8 doesn't support -ffile-prefix-map, disabling `debug_paths_relative` option.") env["debug_paths_relative"] = False elif methods.using_clang(env): - if cc_version_major == -1: - print_warning( - "Couldn't detect compiler version, skipping version checks. " - "Build may fail if the compiler doesn't support C++17 fully." - ) # Apple LLVM versions differ from upstream LLVM version \o/, compare # in https://en.wikipedia.org/wiki/Xcode#Toolchain_versions - elif env["platform"] == "macos" or env["platform"] == "ios": + if env["platform"] == "macos" or env["platform"] == "ios": vanilla = methods.is_vanilla_clang(env) if vanilla and cc_version_major < 6: - print_warning( + print_error( "Detected Clang version older than 6, which does not fully support " "C++17. Supported versions are Clang 6 and later." ) @@ -713,6 +700,28 @@ elif methods.using_clang(env): if env["debug_paths_relative"] and cc_version_major < 10: print_warning("Clang < 10 doesn't support -ffile-prefix-map, disabling `debug_paths_relative` option.") env["debug_paths_relative"] = False +elif env.msvc: + # Ensure latest minor builds of Visual Studio 2017/2019. + # https://github.com/godotengine/godot/pull/94995#issuecomment-2336464574 + if cc_version_major == 16 and cc_version_minor < 11: + print_error( + "Detected Visual Studio 2019 version older than 16.11, which has bugs " + "when compiling Godot. Use a newer VS2019 version, or VS2022." + ) + Exit(255) + if cc_version_major == 15 and cc_version_minor < 9: + print_error( + "Detected Visual Studio 2017 version older than 15.9, which has bugs " + "when compiling Godot. Use a newer VS2017 version, or VS2019/VS2022." + ) + Exit(255) + if cc_version_major < 15: + print_error( + "Detected Visual Studio 2015 or earlier, which is unsupported in Godot. " + "Supported versions are Visual Studio 2017 and later." + ) + Exit(255) + # Set optimize and debug_symbols flags. # "custom" means do nothing and let users set their own optimization flags. @@ -790,13 +799,17 @@ if env["lto"] != "none": # This needs to come after `configure`, otherwise we don't have env.msvc. if not env.msvc: # Specifying GNU extensions support explicitly, which are supported by - # both GCC and Clang. Both currently default to gnu11 and gnu++14. + # both GCC and Clang. Both currently default to gnu11 and gnu++17. env.Prepend(CFLAGS=["-std=gnu11"]) env.Prepend(CXXFLAGS=["-std=gnu++17"]) else: - # MSVC doesn't have clear C standard support, /std only covers C++. - # We apply it to CCFLAGS (both C and C++ code) in case it impacts C features. - env.Prepend(CCFLAGS=["/std:c++17"]) + # MSVC started offering C standard support with Visual Studio 2019 16.8, which covers all + # of our supported VS2019 & VS2022 versions; VS2017 will only pass the C++ standard. + env.Prepend(CXXFLAGS=["/std:c++17"]) + if cc_version_major < 16: + print_warning("Visual Studio 2017 cannot specify a C-Standard.") + else: + env.Prepend(CFLAGS=["/std:c11"]) # MSVC is non-conforming with the C++ standard by default, so we enable more conformance. # Note that this is still not complete conformance, as certain Windows-related headers # don't compile under complete conformance. diff --git a/core/core_constants.cpp b/core/core_constants.cpp index 68af5abf66..25da49fa5c 100644 --- a/core/core_constants.cpp +++ b/core/core_constants.cpp @@ -677,6 +677,7 @@ void register_global_constants() { BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_NODE_TYPE); BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_HIDE_QUATERNION_EDIT); BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_PASSWORD); + BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_TOOL_BUTTON); BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_MAX); BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_NONE); diff --git a/core/extension/extension_api_dump.cpp b/core/extension/extension_api_dump.cpp index 4042d6b80d..c5f7502c12 100644 --- a/core/extension/extension_api_dump.cpp +++ b/core/extension/extension_api_dump.cpp @@ -1017,6 +1017,7 @@ Dictionary GDExtensionAPIDump::generate_extension_api(bool p_include_docs) { d2["name"] = String(method_name); d2["is_const"] = (F.flags & METHOD_FLAG_CONST) ? true : false; d2["is_static"] = (F.flags & METHOD_FLAG_STATIC) ? true : false; + d2["is_required"] = (F.flags & METHOD_FLAG_VIRTUAL_REQUIRED) ? true : false; d2["is_vararg"] = false; d2["is_virtual"] = true; // virtual functions have no hash since no MethodBind is involved diff --git a/core/extension/make_wrappers.py b/core/extension/make_wrappers.py index 54f4fd5579..665b6f0f91 100644 --- a/core/extension/make_wrappers.py +++ b/core/extension/make_wrappers.py @@ -55,10 +55,10 @@ def generate_mod_version(argcount, const=False, returns=False): proto_ex = """ #define EXBIND$VER($RETTYPE m_name$ARG) \\ -GDVIRTUAL$VER($RETTYPE_##m_name$ARG)\\ +GDVIRTUAL$VER_REQUIRED($RETTYPE_##m_name$ARG)\\ virtual $RETVAL m_name($FUNCARGS) $CONST override { \\ $RETPRE\\ - GDVIRTUAL_REQUIRED_CALL(_##m_name$CALLARGS$RETREF);\\ + GDVIRTUAL_CALL(_##m_name$CALLARGS$RETREF);\\ $RETPOST\\ } """ diff --git a/core/object/make_virtuals.py b/core/object/make_virtuals.py index 7a85753072..3df26e3b73 100644 --- a/core/object/make_virtuals.py +++ b/core/object/make_virtuals.py @@ -2,7 +2,6 @@ proto = """#define GDVIRTUAL$VER($RET m_name $ARG)\\ StringName _gdvirtual_##m_name##_sn = #m_name;\\ mutable bool _gdvirtual_##m_name##_initialized = false;\\ mutable void *_gdvirtual_##m_name = nullptr;\\ - template <bool required>\\ _FORCE_INLINE_ bool _gdvirtual_##m_name##_call($CALLARGS) $CONST {\\ ScriptInstance *_script_instance = ((Object *)(this))->get_script_instance();\\ if (_script_instance) {\\ @@ -36,10 +35,8 @@ proto = """#define GDVIRTUAL$VER($RET m_name $ARG)\\ }\\ return true;\\ }\\ - if (required) {\\ - ERR_PRINT_ONCE("Required virtual method " + get_class() + "::" + #m_name + " must be overridden before calling.");\\ - $RVOID\\ - }\\ + $REQCHECK\\ + $RVOID\\ return false;\\ }\\ _FORCE_INLINE_ bool _gdvirtual_##m_name##_overridden() const {\\ @@ -73,10 +70,11 @@ proto = """#define GDVIRTUAL$VER($RET m_name $ARG)\\ """ -def generate_version(argcount, const=False, returns=False): +def generate_version(argcount, const=False, returns=False, required=False): s = proto sproto = str(argcount) method_info = "" + method_flags = "METHOD_FLAG_VIRTUAL" if returns: sproto += "R" s = s.replace("$RET", "m_ret,") @@ -86,17 +84,27 @@ def generate_version(argcount, const=False, returns=False): method_info += "\t\tmethod_info.return_val_metadata = GetTypeInfo<m_ret>::METADATA;" else: s = s.replace("$RET ", "") - s = s.replace("\t\t\t$RVOID\\\n", "") + s = s.replace("\t\t$RVOID\\\n", "") s = s.replace("\t\t\t$CALLPTRRETDEF\\\n", "") if const: sproto += "C" + method_flags += " | METHOD_FLAG_CONST" s = s.replace("$CONST", "const") - s = s.replace("$METHOD_FLAGS", "METHOD_FLAG_VIRTUAL | METHOD_FLAG_CONST") else: s = s.replace("$CONST ", "") - s = s.replace("$METHOD_FLAGS", "METHOD_FLAG_VIRTUAL") + if required: + sproto += "_REQUIRED" + method_flags += " | METHOD_FLAG_VIRTUAL_REQUIRED" + s = s.replace( + "$REQCHECK", + 'ERR_PRINT_ONCE("Required virtual method " + get_class() + "::" + #m_name + " must be overridden before calling.");', + ) + else: + s = s.replace("\t\t$REQCHECK\\\n", "") + + s = s.replace("$METHOD_FLAGS", method_flags) s = s.replace("$VER", sproto) argtext = "" callargtext = "" @@ -198,6 +206,10 @@ def run(target, source, env): txt += generate_version(i, False, True) txt += generate_version(i, True, False) txt += generate_version(i, True, True) + txt += generate_version(i, False, False, True) + txt += generate_version(i, False, True, True) + txt += generate_version(i, True, False, True) + txt += generate_version(i, True, True, True) txt += "#endif // GDVIRTUAL_GEN_H\n" diff --git a/core/object/object.h b/core/object/object.h index 763e2974b9..110d2790c5 100644 --- a/core/object/object.h +++ b/core/object/object.h @@ -87,6 +87,7 @@ enum PropertyHint { PROPERTY_HINT_PASSWORD, PROPERTY_HINT_LAYERS_AVOIDANCE, PROPERTY_HINT_DICTIONARY_TYPE, + PROPERTY_HINT_TOOL_BUTTON, PROPERTY_HINT_MAX, }; @@ -215,6 +216,7 @@ enum MethodFlags { METHOD_FLAG_VARARG = 16, METHOD_FLAG_STATIC = 32, METHOD_FLAG_OBJECT_CORE = 64, + METHOD_FLAG_VIRTUAL_REQUIRED = 128, METHOD_FLAGS_DEFAULT = METHOD_FLAG_NORMAL, }; @@ -368,11 +370,8 @@ struct ObjectGDExtension { #endif }; -#define GDVIRTUAL_CALL(m_name, ...) _gdvirtual_##m_name##_call<false>(__VA_ARGS__) -#define GDVIRTUAL_CALL_PTR(m_obj, m_name, ...) m_obj->_gdvirtual_##m_name##_call<false>(__VA_ARGS__) - -#define GDVIRTUAL_REQUIRED_CALL(m_name, ...) _gdvirtual_##m_name##_call<true>(__VA_ARGS__) -#define GDVIRTUAL_REQUIRED_CALL_PTR(m_obj, m_name, ...) m_obj->_gdvirtual_##m_name##_call<true>(__VA_ARGS__) +#define GDVIRTUAL_CALL(m_name, ...) _gdvirtual_##m_name##_call(__VA_ARGS__) +#define GDVIRTUAL_CALL_PTR(m_obj, m_name, ...) m_obj->_gdvirtual_##m_name##_call(__VA_ARGS__) #ifdef DEBUG_METHODS_ENABLED #define GDVIRTUAL_BIND(m_name, ...) ::ClassDB::add_virtual_method(get_class_static(), _gdvirtual_##m_name##_get_method_info(), true, sarray(__VA_ARGS__)); diff --git a/core/object/script_language_extension.h b/core/object/script_language_extension.h index bc773c5ad3..d2dce34d4f 100644 --- a/core/object/script_language_extension.h +++ b/core/object/script_language_extension.h @@ -57,16 +57,16 @@ public: EXBIND1RC(bool, inherits_script, const Ref<Script> &) EXBIND0RC(StringName, get_instance_base_type) - GDVIRTUAL1RC(GDExtensionPtr<void>, _instance_create, Object *) + GDVIRTUAL1RC_REQUIRED(GDExtensionPtr<void>, _instance_create, Object *) virtual ScriptInstance *instance_create(Object *p_this) override { GDExtensionPtr<void> ret = nullptr; - GDVIRTUAL_REQUIRED_CALL(_instance_create, p_this, ret); + GDVIRTUAL_CALL(_instance_create, p_this, ret); return reinterpret_cast<ScriptInstance *>(ret.operator void *()); } - GDVIRTUAL1RC(GDExtensionPtr<void>, _placeholder_instance_create, Object *) + GDVIRTUAL1RC_REQUIRED(GDExtensionPtr<void>, _placeholder_instance_create, Object *) PlaceHolderScriptInstance *placeholder_instance_create(Object *p_this) override { GDExtensionPtr<void> ret = nullptr; - GDVIRTUAL_REQUIRED_CALL(_placeholder_instance_create, p_this, ret); + GDVIRTUAL_CALL(_placeholder_instance_create, p_this, ret); return reinterpret_cast<PlaceHolderScriptInstance *>(ret.operator void *()); } @@ -76,12 +76,12 @@ public: EXBIND1(set_source_code, const String &) EXBIND1R(Error, reload, bool) - GDVIRTUAL0RC(TypedArray<Dictionary>, _get_documentation) + GDVIRTUAL0RC_REQUIRED(TypedArray<Dictionary>, _get_documentation) GDVIRTUAL0RC(String, _get_class_icon_path) #ifdef TOOLS_ENABLED virtual Vector<DocData::ClassDoc> get_documentation() const override { TypedArray<Dictionary> doc; - GDVIRTUAL_REQUIRED_CALL(_get_documentation, doc); + GDVIRTUAL_CALL(_get_documentation, doc); Vector<DocData::ClassDoc> class_doc; for (int i = 0; i < doc.size(); i++) { @@ -114,10 +114,10 @@ public: return Script::get_script_method_argument_count(p_method, r_is_valid); } - GDVIRTUAL1RC(Dictionary, _get_method_info, const StringName &) + GDVIRTUAL1RC_REQUIRED(Dictionary, _get_method_info, const StringName &) virtual MethodInfo get_method_info(const StringName &p_method) const override { Dictionary mi; - GDVIRTUAL_REQUIRED_CALL(_get_method_info, p_method, mi); + GDVIRTUAL_CALL(_get_method_info, p_method, mi); return MethodInfo::from_dict(mi); } @@ -133,47 +133,47 @@ public: EXBIND0RC(ScriptLanguage *, get_language) EXBIND1RC(bool, has_script_signal, const StringName &) - GDVIRTUAL0RC(TypedArray<Dictionary>, _get_script_signal_list) + GDVIRTUAL0RC_REQUIRED(TypedArray<Dictionary>, _get_script_signal_list) virtual void get_script_signal_list(List<MethodInfo> *r_signals) const override { TypedArray<Dictionary> sl; - GDVIRTUAL_REQUIRED_CALL(_get_script_signal_list, sl); + GDVIRTUAL_CALL(_get_script_signal_list, sl); for (int i = 0; i < sl.size(); i++) { r_signals->push_back(MethodInfo::from_dict(sl[i])); } } - GDVIRTUAL1RC(bool, _has_property_default_value, const StringName &) - GDVIRTUAL1RC(Variant, _get_property_default_value, const StringName &) + GDVIRTUAL1RC_REQUIRED(bool, _has_property_default_value, const StringName &) + GDVIRTUAL1RC_REQUIRED(Variant, _get_property_default_value, const StringName &) virtual bool get_property_default_value(const StringName &p_property, Variant &r_value) const override { bool has_dv = false; - if (!GDVIRTUAL_REQUIRED_CALL(_has_property_default_value, p_property, has_dv) || !has_dv) { + if (!GDVIRTUAL_CALL(_has_property_default_value, p_property, has_dv) || !has_dv) { return false; } Variant ret; - GDVIRTUAL_REQUIRED_CALL(_get_property_default_value, p_property, ret); + GDVIRTUAL_CALL(_get_property_default_value, p_property, ret); r_value = ret; return true; } EXBIND0(update_exports) - GDVIRTUAL0RC(TypedArray<Dictionary>, _get_script_method_list) + GDVIRTUAL0RC_REQUIRED(TypedArray<Dictionary>, _get_script_method_list) virtual void get_script_method_list(List<MethodInfo> *r_methods) const override { TypedArray<Dictionary> sl; - GDVIRTUAL_REQUIRED_CALL(_get_script_method_list, sl); + GDVIRTUAL_CALL(_get_script_method_list, sl); for (int i = 0; i < sl.size(); i++) { r_methods->push_back(MethodInfo::from_dict(sl[i])); } } - GDVIRTUAL0RC(TypedArray<Dictionary>, _get_script_property_list) + GDVIRTUAL0RC_REQUIRED(TypedArray<Dictionary>, _get_script_property_list) virtual void get_script_property_list(List<PropertyInfo> *r_propertys) const override { TypedArray<Dictionary> sl; - GDVIRTUAL_REQUIRED_CALL(_get_script_property_list, sl); + GDVIRTUAL_CALL(_get_script_property_list, sl); for (int i = 0; i < sl.size(); i++) { r_propertys->push_back(PropertyInfo::from_dict(sl[i])); } @@ -181,21 +181,21 @@ public: EXBIND1RC(int, get_member_line, const StringName &) - GDVIRTUAL0RC(Dictionary, _get_constants) + GDVIRTUAL0RC_REQUIRED(Dictionary, _get_constants) virtual void get_constants(HashMap<StringName, Variant> *p_constants) override { Dictionary constants; - GDVIRTUAL_REQUIRED_CALL(_get_constants, constants); + GDVIRTUAL_CALL(_get_constants, constants); List<Variant> keys; constants.get_key_list(&keys); for (const Variant &K : keys) { p_constants->insert(K, constants[K]); } } - GDVIRTUAL0RC(TypedArray<StringName>, _get_members) + GDVIRTUAL0RC_REQUIRED(TypedArray<StringName>, _get_members) virtual void get_members(HashSet<StringName> *p_members) override { TypedArray<StringName> members; - GDVIRTUAL_REQUIRED_CALL(_get_members, members); + GDVIRTUAL_CALL(_get_members, members); for (int i = 0; i < members.size(); i++) { p_members->insert(members[i]); } @@ -203,11 +203,11 @@ public: EXBIND0RC(bool, is_placeholder_fallback_enabled) - GDVIRTUAL0RC(Variant, _get_rpc_config) + GDVIRTUAL0RC_REQUIRED(Variant, _get_rpc_config) virtual Variant get_rpc_config() const override { Variant ret; - GDVIRTUAL_REQUIRED_CALL(_get_rpc_config, ret); + GDVIRTUAL_CALL(_get_rpc_config, ret); return ret; } @@ -233,22 +233,22 @@ public: /* EDITOR FUNCTIONS */ - GDVIRTUAL0RC(Vector<String>, _get_reserved_words) + GDVIRTUAL0RC_REQUIRED(Vector<String>, _get_reserved_words) virtual void get_reserved_words(List<String> *p_words) const override { Vector<String> ret; - GDVIRTUAL_REQUIRED_CALL(_get_reserved_words, ret); + GDVIRTUAL_CALL(_get_reserved_words, ret); for (int i = 0; i < ret.size(); i++) { p_words->push_back(ret[i]); } } EXBIND1RC(bool, is_control_flow_keyword, const String &) - GDVIRTUAL0RC(Vector<String>, _get_comment_delimiters) + GDVIRTUAL0RC_REQUIRED(Vector<String>, _get_comment_delimiters) virtual void get_comment_delimiters(List<String> *p_words) const override { Vector<String> ret; - GDVIRTUAL_REQUIRED_CALL(_get_comment_delimiters, ret); + GDVIRTUAL_CALL(_get_comment_delimiters, ret); for (int i = 0; i < ret.size(); i++) { p_words->push_back(ret[i]); } @@ -264,11 +264,11 @@ public: } } - GDVIRTUAL0RC(Vector<String>, _get_string_delimiters) + GDVIRTUAL0RC_REQUIRED(Vector<String>, _get_string_delimiters) virtual void get_string_delimiters(List<String> *p_words) const override { Vector<String> ret; - GDVIRTUAL_REQUIRED_CALL(_get_string_delimiters, ret); + GDVIRTUAL_CALL(_get_string_delimiters, ret); for (int i = 0; i < ret.size(); i++) { p_words->push_back(ret[i]); } @@ -276,11 +276,11 @@ public: EXBIND3RC(Ref<Script>, make_template, const String &, const String &, const String &) - GDVIRTUAL1RC(TypedArray<Dictionary>, _get_built_in_templates, StringName) + GDVIRTUAL1RC_REQUIRED(TypedArray<Dictionary>, _get_built_in_templates, StringName) virtual Vector<ScriptTemplate> get_built_in_templates(const StringName &p_object) override { TypedArray<Dictionary> ret; - GDVIRTUAL_REQUIRED_CALL(_get_built_in_templates, p_object, ret); + GDVIRTUAL_CALL(_get_built_in_templates, p_object, ret); Vector<ScriptTemplate> stret; for (int i = 0; i < ret.size(); i++) { Dictionary d = ret[i]; @@ -304,10 +304,10 @@ public: EXBIND0R(bool, is_using_templates) - GDVIRTUAL6RC(Dictionary, _validate, const String &, const String &, bool, bool, bool, bool) + GDVIRTUAL6RC_REQUIRED(Dictionary, _validate, const String &, const String &, bool, bool, bool, bool) virtual bool validate(const String &p_script, const String &p_path = "", List<String> *r_functions = nullptr, List<ScriptError> *r_errors = nullptr, List<Warning> *r_warnings = nullptr, HashSet<int> *r_safe_lines = nullptr) const override { Dictionary ret; - GDVIRTUAL_REQUIRED_CALL(_validate, p_script, p_path, r_functions != nullptr, r_errors != nullptr, r_warnings != nullptr, r_safe_lines != nullptr, ret); + GDVIRTUAL_CALL(_validate, p_script, p_path, r_functions != nullptr, r_errors != nullptr, r_warnings != nullptr, r_safe_lines != nullptr, ret); if (!ret.has("valid")) { return false; } @@ -371,10 +371,10 @@ public: } EXBIND1RC(String, validate_path, const String &) - GDVIRTUAL0RC(Object *, _create_script) + GDVIRTUAL0RC_REQUIRED(Object *, _create_script) Script *create_script() const override { Object *ret = nullptr; - GDVIRTUAL_REQUIRED_CALL(_create_script, ret); + GDVIRTUAL_CALL(_create_script, ret); return Object::cast_to<Script>(ret); } #ifndef DISABLE_DEPRECATED @@ -400,11 +400,11 @@ public: return ScriptNameCasing::SCRIPT_NAME_CASING_SNAKE_CASE; } - GDVIRTUAL3RC(Dictionary, _complete_code, const String &, const String &, Object *) + GDVIRTUAL3RC_REQUIRED(Dictionary, _complete_code, const String &, const String &, Object *) virtual Error complete_code(const String &p_code, const String &p_path, Object *p_owner, List<CodeCompletionOption> *r_options, bool &r_force, String &r_call_hint) override { Dictionary ret; - GDVIRTUAL_REQUIRED_CALL(_complete_code, p_code, p_path, p_owner, ret); + GDVIRTUAL_CALL(_complete_code, p_code, p_path, p_owner, ret); if (!ret.has("result")) { return ERR_UNAVAILABLE; } @@ -449,11 +449,11 @@ public: return result; } - GDVIRTUAL4RC(Dictionary, _lookup_code, const String &, const String &, const String &, Object *) + GDVIRTUAL4RC_REQUIRED(Dictionary, _lookup_code, const String &, const String &, const String &, Object *) virtual Error lookup_code(const String &p_code, const String &p_symbol, const String &p_path, Object *p_owner, LookupResult &r_result) override { Dictionary ret; - GDVIRTUAL_REQUIRED_CALL(_lookup_code, p_code, p_symbol, p_path, p_owner, ret); + GDVIRTUAL_CALL(_lookup_code, p_code, p_symbol, p_path, p_owner, ret); if (!ret.has("result")) { return ERR_UNAVAILABLE; } @@ -474,10 +474,10 @@ public: return result; } - GDVIRTUAL3RC(String, _auto_indent_code, const String &, int, int) + GDVIRTUAL3RC_REQUIRED(String, _auto_indent_code, const String &, int, int) virtual void auto_indent_code(String &p_code, int p_from_line, int p_to_line) const override { String ret; - GDVIRTUAL_REQUIRED_CALL(_auto_indent_code, p_code, p_from_line, p_to_line, ret); + GDVIRTUAL_CALL(_auto_indent_code, p_code, p_from_line, p_to_line, ret); p_code = ret; } EXBIND2(add_global_constant, const StringName &, const Variant &) @@ -496,10 +496,10 @@ public: EXBIND1RC(String, debug_get_stack_level_function, int) EXBIND1RC(String, debug_get_stack_level_source, int) - GDVIRTUAL3R(Dictionary, _debug_get_stack_level_locals, int, int, int) + GDVIRTUAL3R_REQUIRED(Dictionary, _debug_get_stack_level_locals, int, int, int) virtual void debug_get_stack_level_locals(int p_level, List<String> *p_locals, List<Variant> *p_values, int p_max_subitems = -1, int p_max_depth = -1) override { Dictionary ret; - GDVIRTUAL_REQUIRED_CALL(_debug_get_stack_level_locals, p_level, p_max_subitems, p_max_depth, ret); + GDVIRTUAL_CALL(_debug_get_stack_level_locals, p_level, p_max_subitems, p_max_depth, ret); if (ret.size() == 0) { return; } @@ -516,10 +516,10 @@ public: } } } - GDVIRTUAL3R(Dictionary, _debug_get_stack_level_members, int, int, int) + GDVIRTUAL3R_REQUIRED(Dictionary, _debug_get_stack_level_members, int, int, int) virtual void debug_get_stack_level_members(int p_level, List<String> *p_members, List<Variant> *p_values, int p_max_subitems = -1, int p_max_depth = -1) override { Dictionary ret; - GDVIRTUAL_REQUIRED_CALL(_debug_get_stack_level_members, p_level, p_max_subitems, p_max_depth, ret); + GDVIRTUAL_CALL(_debug_get_stack_level_members, p_level, p_max_subitems, p_max_depth, ret); if (ret.size() == 0) { return; } @@ -536,17 +536,17 @@ public: } } } - GDVIRTUAL1R(GDExtensionPtr<void>, _debug_get_stack_level_instance, int) + GDVIRTUAL1R_REQUIRED(GDExtensionPtr<void>, _debug_get_stack_level_instance, int) virtual ScriptInstance *debug_get_stack_level_instance(int p_level) override { GDExtensionPtr<void> ret = nullptr; - GDVIRTUAL_REQUIRED_CALL(_debug_get_stack_level_instance, p_level, ret); + GDVIRTUAL_CALL(_debug_get_stack_level_instance, p_level, ret); return reinterpret_cast<ScriptInstance *>(ret.operator void *()); } - GDVIRTUAL2R(Dictionary, _debug_get_globals, int, int) + GDVIRTUAL2R_REQUIRED(Dictionary, _debug_get_globals, int, int) virtual void debug_get_globals(List<String> *p_globals, List<Variant> *p_values, int p_max_subitems = -1, int p_max_depth = -1) override { Dictionary ret; - GDVIRTUAL_REQUIRED_CALL(_debug_get_globals, p_max_subitems, p_max_depth, ret); + GDVIRTUAL_CALL(_debug_get_globals, p_max_subitems, p_max_depth, ret); if (ret.size() == 0) { return; } @@ -566,10 +566,10 @@ public: EXBIND4R(String, debug_parse_stack_level_expression, int, const String &, int, int) - GDVIRTUAL0R(TypedArray<Dictionary>, _debug_get_current_stack_info) + GDVIRTUAL0R_REQUIRED(TypedArray<Dictionary>, _debug_get_current_stack_info) virtual Vector<StackInfo> debug_get_current_stack_info() override { TypedArray<Dictionary> ret; - GDVIRTUAL_REQUIRED_CALL(_debug_get_current_stack_info, ret); + GDVIRTUAL_CALL(_debug_get_current_stack_info, ret); Vector<StackInfo> sret; for (const Variant &var : ret) { StackInfo si; @@ -590,29 +590,29 @@ public: EXBIND2(reload_tool_script, const Ref<Script> &, bool) /* LOADER FUNCTIONS */ - GDVIRTUAL0RC(PackedStringArray, _get_recognized_extensions) + GDVIRTUAL0RC_REQUIRED(PackedStringArray, _get_recognized_extensions) virtual void get_recognized_extensions(List<String> *p_extensions) const override { PackedStringArray ret; - GDVIRTUAL_REQUIRED_CALL(_get_recognized_extensions, ret); + GDVIRTUAL_CALL(_get_recognized_extensions, ret); for (int i = 0; i < ret.size(); i++) { p_extensions->push_back(ret[i]); } } - GDVIRTUAL0RC(TypedArray<Dictionary>, _get_public_functions) + GDVIRTUAL0RC_REQUIRED(TypedArray<Dictionary>, _get_public_functions) virtual void get_public_functions(List<MethodInfo> *p_functions) const override { TypedArray<Dictionary> ret; - GDVIRTUAL_REQUIRED_CALL(_get_public_functions, ret); + GDVIRTUAL_CALL(_get_public_functions, ret); for (const Variant &var : ret) { MethodInfo mi = MethodInfo::from_dict(var); p_functions->push_back(mi); } } - GDVIRTUAL0RC(Dictionary, _get_public_constants) + GDVIRTUAL0RC_REQUIRED(Dictionary, _get_public_constants) virtual void get_public_constants(List<Pair<String, Variant>> *p_constants) const override { Dictionary ret; - GDVIRTUAL_REQUIRED_CALL(_get_public_constants, ret); + GDVIRTUAL_CALL(_get_public_constants, ret); for (int i = 0; i < ret.size(); i++) { Dictionary d = ret[i]; ERR_CONTINUE(!d.has("name")); @@ -620,10 +620,10 @@ public: p_constants->push_back(Pair<String, Variant>(d["name"], d["value"])); } } - GDVIRTUAL0RC(TypedArray<Dictionary>, _get_public_annotations) + GDVIRTUAL0RC_REQUIRED(TypedArray<Dictionary>, _get_public_annotations) virtual void get_public_annotations(List<MethodInfo> *p_annotations) const override { TypedArray<Dictionary> ret; - GDVIRTUAL_REQUIRED_CALL(_get_public_annotations, ret); + GDVIRTUAL_CALL(_get_public_annotations, ret); for (const Variant &var : ret) { MethodInfo mi = MethodInfo::from_dict(var); p_annotations->push_back(mi); @@ -634,19 +634,19 @@ public: EXBIND0(profiling_stop) EXBIND1(profiling_set_save_native_calls, bool) - GDVIRTUAL2R(int, _profiling_get_accumulated_data, GDExtensionPtr<ScriptLanguageExtensionProfilingInfo>, int) + GDVIRTUAL2R_REQUIRED(int, _profiling_get_accumulated_data, GDExtensionPtr<ScriptLanguageExtensionProfilingInfo>, int) virtual int profiling_get_accumulated_data(ProfilingInfo *p_info_arr, int p_info_max) override { int ret = 0; - GDVIRTUAL_REQUIRED_CALL(_profiling_get_accumulated_data, p_info_arr, p_info_max, ret); + GDVIRTUAL_CALL(_profiling_get_accumulated_data, p_info_arr, p_info_max, ret); return ret; } - GDVIRTUAL2R(int, _profiling_get_frame_data, GDExtensionPtr<ScriptLanguageExtensionProfilingInfo>, int) + GDVIRTUAL2R_REQUIRED(int, _profiling_get_frame_data, GDExtensionPtr<ScriptLanguageExtensionProfilingInfo>, int) virtual int profiling_get_frame_data(ProfilingInfo *p_info_arr, int p_info_max) override { int ret = 0; - GDVIRTUAL_REQUIRED_CALL(_profiling_get_frame_data, p_info_arr, p_info_max, ret); + GDVIRTUAL_CALL(_profiling_get_frame_data, p_info_arr, p_info_max, ret); return ret; } @@ -654,11 +654,11 @@ public: EXBIND1RC(bool, handles_global_class_type, const String &) - GDVIRTUAL1RC(Dictionary, _get_global_class_name, const String &) + GDVIRTUAL1RC_REQUIRED(Dictionary, _get_global_class_name, const String &) virtual String get_global_class_name(const String &p_path, String *r_base_type = nullptr, String *r_icon_path = nullptr) const override { Dictionary ret; - GDVIRTUAL_REQUIRED_CALL(_get_global_class_name, p_path, ret); + GDVIRTUAL_CALL(_get_global_class_name, p_path, ret); if (!ret.has("name")) { return String(); } diff --git a/core/variant/variant_call.cpp b/core/variant/variant_call.cpp index 63fb5e8d94..ab33c9db55 100644 --- a/core/variant/variant_call.cpp +++ b/core/variant/variant_call.cpp @@ -657,7 +657,23 @@ static _FORCE_INLINE_ void vc_ptrcall(void (*method)(T *, P...), void *p_base, c } \ }; +#define VARCALL_PACKED_GETTER(m_packed_type, m_return_type) \ + static m_return_type func_##m_packed_type##_get(m_packed_type *p_instance, int64_t p_index) { \ + return p_instance->get(p_index); \ + } + struct _VariantCall { + VARCALL_PACKED_GETTER(PackedByteArray, uint8_t) + VARCALL_PACKED_GETTER(PackedColorArray, Color) + VARCALL_PACKED_GETTER(PackedFloat32Array, float) + VARCALL_PACKED_GETTER(PackedFloat64Array, double) + VARCALL_PACKED_GETTER(PackedInt32Array, int32_t) + VARCALL_PACKED_GETTER(PackedInt64Array, int64_t) + VARCALL_PACKED_GETTER(PackedStringArray, String) + VARCALL_PACKED_GETTER(PackedVector2Array, Vector2) + VARCALL_PACKED_GETTER(PackedVector3Array, Vector3) + VARCALL_PACKED_GETTER(PackedVector4Array, Vector4) + static String func_PackedByteArray_get_string_from_ascii(PackedByteArray *p_instance) { String s; if (p_instance->size() > 0) { @@ -2268,6 +2284,7 @@ static void _register_variant_builtin_methods_misc() { bind_method(Dictionary, duplicate, sarray("deep"), varray(false)); bind_method(Dictionary, get, sarray("key", "default"), varray(Variant())); bind_method(Dictionary, get_or_add, sarray("key", "default"), varray(Variant())); + bind_method(Dictionary, set, sarray("key", "value"), varray()); bind_method(Dictionary, is_typed, sarray(), varray()); bind_method(Dictionary, is_typed_key, sarray(), varray()); bind_method(Dictionary, is_typed_value, sarray(), varray()); @@ -2293,6 +2310,8 @@ static void _register_variant_builtin_methods_array() { bind_method(Array, clear, sarray(), varray()); bind_method(Array, hash, sarray(), varray()); bind_method(Array, assign, sarray("array"), varray()); + bind_method(Array, get, sarray("index"), varray()); + bind_method(Array, set, sarray("index", "value"), varray()); bind_method(Array, push_back, sarray("value"), varray()); bind_method(Array, push_front, sarray("value"), varray()); bind_method(Array, append, sarray("value"), varray()); @@ -2337,6 +2356,18 @@ static void _register_variant_builtin_methods_array() { bind_method(Array, make_read_only, sarray(), varray()); bind_method(Array, is_read_only, sarray(), varray()); + /* Packed*Array get (see VARCALL_PACKED_GETTER macro) */ + bind_function(PackedByteArray, get, _VariantCall::func_PackedByteArray_get, sarray("index"), varray()); + bind_function(PackedColorArray, get, _VariantCall::func_PackedColorArray_get, sarray("index"), varray()); + bind_function(PackedFloat32Array, get, _VariantCall::func_PackedFloat32Array_get, sarray("index"), varray()); + bind_function(PackedFloat64Array, get, _VariantCall::func_PackedFloat64Array_get, sarray("index"), varray()); + bind_function(PackedInt32Array, get, _VariantCall::func_PackedInt32Array_get, sarray("index"), varray()); + bind_function(PackedInt64Array, get, _VariantCall::func_PackedInt64Array_get, sarray("index"), varray()); + bind_function(PackedStringArray, get, _VariantCall::func_PackedStringArray_get, sarray("index"), varray()); + bind_function(PackedVector2Array, get, _VariantCall::func_PackedVector2Array_get, sarray("index"), varray()); + bind_function(PackedVector3Array, get, _VariantCall::func_PackedVector3Array_get, sarray("index"), varray()); + bind_function(PackedVector4Array, get, _VariantCall::func_PackedVector4Array_get, sarray("index"), varray()); + /* Byte Array */ bind_method(PackedByteArray, size, sarray(), varray()); bind_method(PackedByteArray, is_empty, sarray(), varray()); diff --git a/doc/classes/@GlobalScope.xml b/doc/classes/@GlobalScope.xml index a86f41cd9c..63d20242d6 100644 --- a/doc/classes/@GlobalScope.xml +++ b/doc/classes/@GlobalScope.xml @@ -2933,7 +2933,15 @@ <constant name="PROPERTY_HINT_PASSWORD" value="36" enum="PropertyHint"> Hints that a string property is a password, and every character is replaced with the secret character. </constant> - <constant name="PROPERTY_HINT_MAX" value="39" enum="PropertyHint"> + <constant name="PROPERTY_HINT_TOOL_BUTTON" value="39" enum="PropertyHint"> + Hints that a [Callable] property should be displayed as a clickable button. When the button is pressed, the callable is called. The hint string specifies the button text and optionally an icon from the [code]"EditorIcons"[/code] theme type. + [codeblock lang=text] + "Click me!" - A button with the text "Click me!" and the default "Callable" icon. + "Click me!,ColorRect" - A button with the text "Click me!" and the "ColorRect" icon. + [/codeblock] + [b]Note:[/b] A [Callable] cannot be properly serialized and stored in a file, so it is recommended to use [constant PROPERTY_USAGE_EDITOR] instead of [constant PROPERTY_USAGE_DEFAULT]. + </constant> + <constant name="PROPERTY_HINT_MAX" value="40" enum="PropertyHint"> Represents the size of the [enum PropertyHint] enum. </constant> <constant name="PROPERTY_USAGE_NONE" value="0" enum="PropertyUsageFlags" is_bitfield="true"> diff --git a/doc/classes/Array.xml b/doc/classes/Array.xml index adb6be1070..1b7dbf7c41 100644 --- a/doc/classes/Array.xml +++ b/doc/classes/Array.xml @@ -422,6 +422,13 @@ [b]Note:[/b] Unlike with the [code][][/code] operator ([code]array[0][/code]), an error is generated without stopping project execution. </description> </method> + <method name="get" qualifiers="const"> + <return type="Variant" /> + <param index="0" name="index" type="int" /> + <description> + Returns the element at the given [param index] in the array. This is the same as using the [code][][/code] operator ([code]array[index][/code]). + </description> + </method> <method name="get_typed_builtin" qualifiers="const"> <return type="int" /> <description> @@ -693,6 +700,14 @@ Returns the index of the [b]last[/b] element of the array that causes [param method] to return [code]true[/code], or [code]-1[/code] if there are none. The search's start can be specified with [param from], continuing to the beginning of the array. This method is the reverse of [method find_custom]. </description> </method> + <method name="set"> + <return type="void" /> + <param index="0" name="index" type="int" /> + <param index="1" name="value" type="Variant" /> + <description> + Sets the value of the element at the given [param index] to the given [param value]. This will not change the size of the array, it only changes the value at an index already in the array. This is the same as using the [code][][/code] operator ([code]array[index] = value[/code]). + </description> + </method> <method name="shuffle"> <return type="void" /> <description> diff --git a/doc/classes/Dictionary.xml b/doc/classes/Dictionary.xml index feb2a07e4a..4441c3cb79 100644 --- a/doc/classes/Dictionary.xml +++ b/doc/classes/Dictionary.xml @@ -460,6 +460,14 @@ Returns [code]true[/code] if the two dictionaries contain the same keys and values, inner [Dictionary] and [Array] keys and values are compared recursively. </description> </method> + <method name="set"> + <return type="bool" /> + <param index="0" name="key" type="Variant" /> + <param index="1" name="value" type="Variant" /> + <description> + Sets the value of the element at the given [param key] to the given [param value]. This is the same as using the [code][][/code] operator ([code]array[index] = value[/code]). + </description> + </method> <method name="size" qualifiers="const"> <return type="int" /> <description> diff --git a/doc/classes/GraphEdit.xml b/doc/classes/GraphEdit.xml index 670df10a89..3451e427f3 100644 --- a/doc/classes/GraphEdit.xml +++ b/doc/classes/GraphEdit.xml @@ -399,6 +399,11 @@ Emitted when this [GraphEdit] captures a [code]ui_copy[/code] action ([kbd]Ctrl + C[/kbd] by default). In general, this signal indicates that the selected [GraphElement]s should be copied. </description> </signal> + <signal name="cut_nodes_request"> + <description> + Emitted when this [GraphEdit] captures a [code]ui_cut[/code] action ([kbd]Ctrl + X[/kbd] by default). In general, this signal indicates that the selected [GraphElement]s should be cut. + </description> + </signal> <signal name="delete_nodes_request"> <param index="0" name="nodes" type="StringName[]" /> <description> diff --git a/doc/classes/ItemList.xml b/doc/classes/ItemList.xml index a1e5d9cbd9..c60a2ca887 100644 --- a/doc/classes/ItemList.xml +++ b/doc/classes/ItemList.xml @@ -407,13 +407,14 @@ <param index="0" name="at_position" type="Vector2" /> <param index="1" name="mouse_button_index" type="int" /> <description> - Triggered when any mouse click is issued within the rect of the list but on empty space. + Emitted when any mouse click is issued within the rect of the list but on empty space. + [param at_position] is the click position in this control's local coordinate system. </description> </signal> <signal name="item_activated"> <param index="0" name="index" type="int" /> <description> - Triggered when specified list item is activated via double-clicking or by pressing [kbd]Enter[/kbd]. + Emitted when specified list item is activated via double-clicking or by pressing [kbd]Enter[/kbd]. </description> </signal> <signal name="item_clicked"> @@ -421,14 +422,14 @@ <param index="1" name="at_position" type="Vector2" /> <param index="2" name="mouse_button_index" type="int" /> <description> - Triggered when specified list item has been clicked with any mouse button. - The click position is also provided to allow appropriate popup of context menus at the correct location. + Emitted when specified list item has been clicked with any mouse button. + [param at_position] is the click position in this control's local coordinate system. </description> </signal> <signal name="item_selected"> <param index="0" name="index" type="int" /> <description> - Triggered when specified item has been selected. + Emitted when specified item has been selected. Only applicable in single selection mode. [member allow_reselect] must be enabled to reselect an item. </description> </signal> @@ -436,7 +437,7 @@ <param index="0" name="index" type="int" /> <param index="1" name="selected" type="bool" /> <description> - Triggered when a multiple selection is altered on a list allowing multiple selection. + Emitted when a multiple selection is altered on a list allowing multiple selection. </description> </signal> </signals> diff --git a/doc/classes/PackedByteArray.xml b/doc/classes/PackedByteArray.xml index e179c111a2..75193ae8ed 100644 --- a/doc/classes/PackedByteArray.xml +++ b/doc/classes/PackedByteArray.xml @@ -307,6 +307,13 @@ Searches the array for a value and returns its index or [code]-1[/code] if not found. Optionally, the initial search index can be passed. </description> </method> + <method name="get" qualifiers="const"> + <return type="int" /> + <param index="0" name="index" type="int" /> + <description> + Returns the byte at the given [param index] in the array. This is the same as using the [code][][/code] operator ([code]array[index][/code]). + </description> + </method> <method name="get_string_from_ascii" qualifiers="const"> <return type="String" /> <description> diff --git a/doc/classes/PackedColorArray.xml b/doc/classes/PackedColorArray.xml index 57295cb1e3..b9cef0ead6 100644 --- a/doc/classes/PackedColorArray.xml +++ b/doc/classes/PackedColorArray.xml @@ -94,6 +94,13 @@ Searches the array for a value and returns its index or [code]-1[/code] if not found. Optionally, the initial search index can be passed. </description> </method> + <method name="get" qualifiers="const"> + <return type="Color" /> + <param index="0" name="index" type="int" /> + <description> + Returns the [Color] at the given [param index] in the array. This is the same as using the [code][][/code] operator ([code]array[index][/code]). + </description> + </method> <method name="has" qualifiers="const"> <return type="bool" /> <param index="0" name="value" type="Color" /> diff --git a/doc/classes/PackedFloat32Array.xml b/doc/classes/PackedFloat32Array.xml index 2db1386fd0..d421993b8f 100644 --- a/doc/classes/PackedFloat32Array.xml +++ b/doc/classes/PackedFloat32Array.xml @@ -93,6 +93,13 @@ [b]Note:[/b] [constant @GDScript.NAN] doesn't behave the same as other numbers. Therefore, the results from this method may not be accurate if NaNs are included. </description> </method> + <method name="get" qualifiers="const"> + <return type="float" /> + <param index="0" name="index" type="int" /> + <description> + Returns the 32-bit float at the given [param index] in the array. This is the same as using the [code][][/code] operator ([code]array[index][/code]). + </description> + </method> <method name="has" qualifiers="const"> <return type="bool" /> <param index="0" name="value" type="float" /> diff --git a/doc/classes/PackedFloat64Array.xml b/doc/classes/PackedFloat64Array.xml index 0bcee918ed..4622d63258 100644 --- a/doc/classes/PackedFloat64Array.xml +++ b/doc/classes/PackedFloat64Array.xml @@ -94,6 +94,13 @@ [b]Note:[/b] [constant @GDScript.NAN] doesn't behave the same as other numbers. Therefore, the results from this method may not be accurate if NaNs are included. </description> </method> + <method name="get" qualifiers="const"> + <return type="float" /> + <param index="0" name="index" type="int" /> + <description> + Returns the 64-bit float at the given [param index] in the array. This is the same as using the [code][][/code] operator ([code]array[index][/code]). + </description> + </method> <method name="has" qualifiers="const"> <return type="bool" /> <param index="0" name="value" type="float" /> diff --git a/doc/classes/PackedInt32Array.xml b/doc/classes/PackedInt32Array.xml index 93b2ae7394..3a3596b2d0 100644 --- a/doc/classes/PackedInt32Array.xml +++ b/doc/classes/PackedInt32Array.xml @@ -90,6 +90,13 @@ Searches the array for a value and returns its index or [code]-1[/code] if not found. Optionally, the initial search index can be passed. </description> </method> + <method name="get" qualifiers="const"> + <return type="int" /> + <param index="0" name="index" type="int" /> + <description> + Returns the 32-bit integer at the given [param index] in the array. This is the same as using the [code][][/code] operator ([code]array[index][/code]). + </description> + </method> <method name="has" qualifiers="const"> <return type="bool" /> <param index="0" name="value" type="int" /> diff --git a/doc/classes/PackedInt64Array.xml b/doc/classes/PackedInt64Array.xml index 3d34165915..cfaf012a55 100644 --- a/doc/classes/PackedInt64Array.xml +++ b/doc/classes/PackedInt64Array.xml @@ -91,6 +91,13 @@ Searches the array for a value and returns its index or [code]-1[/code] if not found. Optionally, the initial search index can be passed. </description> </method> + <method name="get" qualifiers="const"> + <return type="int" /> + <param index="0" name="index" type="int" /> + <description> + Returns the 64-bit integer at the given [param index] in the array. This is the same as using the [code][][/code] operator ([code]array[index][/code]). + </description> + </method> <method name="has" qualifiers="const"> <return type="bool" /> <param index="0" name="value" type="int" /> diff --git a/doc/classes/PackedStringArray.xml b/doc/classes/PackedStringArray.xml index 621831c7a3..511850d645 100644 --- a/doc/classes/PackedStringArray.xml +++ b/doc/classes/PackedStringArray.xml @@ -97,6 +97,13 @@ Searches the array for a value and returns its index or [code]-1[/code] if not found. Optionally, the initial search index can be passed. </description> </method> + <method name="get" qualifiers="const"> + <return type="String" /> + <param index="0" name="index" type="int" /> + <description> + Returns the [String] at the given [param index] in the array. This is the same as using the [code][][/code] operator ([code]array[index][/code]). + </description> + </method> <method name="has" qualifiers="const"> <return type="bool" /> <param index="0" name="value" type="String" /> diff --git a/doc/classes/PackedVector2Array.xml b/doc/classes/PackedVector2Array.xml index 14a3816353..da41812e0b 100644 --- a/doc/classes/PackedVector2Array.xml +++ b/doc/classes/PackedVector2Array.xml @@ -98,6 +98,13 @@ [b]Note:[/b] Vectors with [constant @GDScript.NAN] elements don't behave the same as other vectors. Therefore, the results from this method may not be accurate if NaNs are included. </description> </method> + <method name="get" qualifiers="const"> + <return type="Vector2" /> + <param index="0" name="index" type="int" /> + <description> + Returns the [Vector2] at the given [param index] in the array. This is the same as using the [code][][/code] operator ([code]array[index][/code]). + </description> + </method> <method name="has" qualifiers="const"> <return type="bool" /> <param index="0" name="value" type="Vector2" /> diff --git a/doc/classes/PackedVector3Array.xml b/doc/classes/PackedVector3Array.xml index 49220c6fd6..d47f2f3cd1 100644 --- a/doc/classes/PackedVector3Array.xml +++ b/doc/classes/PackedVector3Array.xml @@ -97,6 +97,13 @@ [b]Note:[/b] Vectors with [constant @GDScript.NAN] elements don't behave the same as other vectors. Therefore, the results from this method may not be accurate if NaNs are included. </description> </method> + <method name="get" qualifiers="const"> + <return type="Vector3" /> + <param index="0" name="index" type="int" /> + <description> + Returns the [Vector3] at the given [param index] in the array. This is the same as using the [code][][/code] operator ([code]array[index][/code]). + </description> + </method> <method name="has" qualifiers="const"> <return type="bool" /> <param index="0" name="value" type="Vector3" /> diff --git a/doc/classes/PackedVector4Array.xml b/doc/classes/PackedVector4Array.xml index fd0cfeb74b..6dbfc7413d 100644 --- a/doc/classes/PackedVector4Array.xml +++ b/doc/classes/PackedVector4Array.xml @@ -96,6 +96,13 @@ [b]Note:[/b] Vectors with [constant @GDScript.NAN] elements don't behave the same as other vectors. Therefore, the results from this method may not be accurate if NaNs are included. </description> </method> + <method name="get" qualifiers="const"> + <return type="Vector4" /> + <param index="0" name="index" type="int" /> + <description> + Returns the [Vector4] at the given [param index] in the array. This is the same as using the [code][][/code] operator ([code]array[index][/code]). + </description> + </method> <method name="has" qualifiers="const"> <return type="bool" /> <param index="0" name="value" type="Vector4" /> diff --git a/doc/classes/ParticleProcessMaterial.xml b/doc/classes/ParticleProcessMaterial.xml index 28c60194c8..742e0cc44c 100644 --- a/doc/classes/ParticleProcessMaterial.xml +++ b/doc/classes/ParticleProcessMaterial.xml @@ -90,6 +90,7 @@ <members> <member name="alpha_curve" type="Texture2D" setter="set_alpha_curve" getter="get_alpha_curve"> The alpha value of each particle's color will be multiplied by this [CurveTexture] over its lifetime. + [b]Note:[/b] [member alpha_curve] multiplies the particle mesh's vertex colors. To have a visible effect on a [BaseMaterial3D], [member BaseMaterial3D.vertex_color_use_as_albedo] [i]must[/i] be [code]true[/code]. For a [ShaderMaterial], [code]ALBEDO *= COLOR.rgb;[/code] must be inserted in the shader's [code]fragment()[/code] function. Otherwise, [member alpha_curve] will have no visible effect. </member> <member name="angle_curve" type="Texture2D" setter="set_param_texture" getter="get_param_texture"> Each particle's rotation will be animated along this [CurveTexture]. @@ -193,7 +194,7 @@ </member> <member name="emission_curve" type="Texture2D" setter="set_emission_curve" getter="get_emission_curve"> Each particle's color will be multiplied by this [CurveTexture] over its lifetime. - [b]Note:[/b] This property won't have a visible effect unless the render material is marked as unshaded. + [b]Note:[/b] [member emission_curve] multiplies the particle mesh's vertex colors. To have a visible effect on a [BaseMaterial3D], [member BaseMaterial3D.vertex_color_use_as_albedo] [i]must[/i] be [code]true[/code]. For a [ShaderMaterial], [code]ALBEDO *= COLOR.rgb;[/code] must be inserted in the shader's [code]fragment()[/code] function. Otherwise, [member emission_curve] will have no visible effect. </member> <member name="emission_normal_texture" type="Texture2D" setter="set_emission_normal_texture" getter="get_emission_normal_texture"> Particle velocity and rotation will be set by sampling this texture at the same point as the [member emission_point_texture]. Used only in [constant EMISSION_SHAPE_DIRECTED_POINTS]. Can be created automatically from mesh or node by selecting "Create Emission Points from Mesh/Node" under the "Particles" tool in the toolbar. diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml index 7b6d8d0cd3..af5ec41b60 100644 --- a/doc/classes/ProjectSettings.xml +++ b/doc/classes/ProjectSettings.xml @@ -2863,11 +2863,6 @@ </member> <member name="rendering/shading/overrides/force_vertex_shading" type="bool" setter="" getter="" default="false"> If [code]true[/code], forces vertex shading for all rendering. This can increase performance a lot, but also reduces quality immensely. Can be used to optimize performance on low-end mobile devices. - [b]Note:[/b] This setting currently has no effect, as vertex shading is not implemented yet. - </member> - <member name="rendering/shading/overrides/force_vertex_shading.mobile" type="bool" setter="" getter="" default="true"> - Lower-end override for [member rendering/shading/overrides/force_vertex_shading] on mobile devices, due to performance concerns or driver support. - [b]Note:[/b] This setting currently has no effect, as vertex shading is not implemented yet. </member> <member name="rendering/textures/canvas_textures/default_texture_filter" type="int" setter="" getter="" default="1"> The default texture filtering mode to use on [CanvasItem]s. diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp index 65749323fd..c2d1784958 100644 --- a/drivers/gles3/rasterizer_scene_gles3.cpp +++ b/drivers/gles3/rasterizer_scene_gles3.cpp @@ -4125,6 +4125,9 @@ RasterizerSceneGLES3::RasterizerSceneGLES3() { global_defines += "\n#define MAX_DIRECTIONAL_LIGHT_DATA_STRUCTS " + itos(MAX_DIRECTIONAL_LIGHTS) + "\n"; global_defines += "\n#define MAX_FORWARD_LIGHTS " + itos(config->max_lights_per_object) + "u\n"; global_defines += "\n#define MAX_ROUGHNESS_LOD " + itos(sky_globals.roughness_layers - 1) + ".0\n"; + if (config->force_vertex_shading) { + global_defines += "\n#define USE_VERTEX_LIGHTING\n"; + } material_storage->shaders.scene_shader.initialize(global_defines); scene_globals.shader_default_version = material_storage->shaders.scene_shader.version_create(); material_storage->shaders.scene_shader.version_bind_shader(scene_globals.shader_default_version, SceneShaderGLES3::MODE_COLOR); diff --git a/drivers/gles3/shaders/scene.glsl b/drivers/gles3/shaders/scene.glsl index 393ba014c6..9ce10a4488 100644 --- a/drivers/gles3/shaders/scene.glsl +++ b/drivers/gles3/shaders/scene.glsl @@ -248,6 +248,175 @@ uniform lowp uint directional_shadow_index; #endif // !(defined(ADDITIVE_OMNI) || defined(ADDITIVE_SPOT)) #endif // USE_ADDITIVE_LIGHTING +#ifdef USE_VERTEX_LIGHTING + +out vec3 diffuse_light_interp; +out vec3 specular_light_interp; + +#ifdef USE_ADDITIVE_LIGHTING +out vec3 additive_diffuse_light_interp; +out vec3 additive_specular_light_interp; +#endif // USE_ADDITIVE_LIGHTING + +// Directional light data. +#if !defined(DISABLE_LIGHT_DIRECTIONAL) || (!defined(ADDITIVE_OMNI) && !defined(ADDITIVE_SPOT) && defined(USE_ADDITIVE_LIGHTING)) + +struct DirectionalLightData { + mediump vec3 direction; + mediump float energy; + mediump vec3 color; + mediump float size; + lowp uint unused; + lowp uint bake_mode; + mediump float shadow_opacity; + mediump float specular; +}; + +layout(std140) uniform DirectionalLights { // ubo:7 + DirectionalLightData directional_lights[MAX_DIRECTIONAL_LIGHT_DATA_STRUCTS]; +}; +#endif // !DISABLE_LIGHT_DIRECTIONAL + +// Omni and spot light data. +#if !defined(DISABLE_LIGHT_OMNI) || !defined(DISABLE_LIGHT_SPOT) || (defined(ADDITIVE_OMNI) || defined(ADDITIVE_SPOT) && defined(USE_ADDITIVE_LIGHTING)) + +struct LightData { // This structure needs to be as packed as possible. + highp vec3 position; + highp float inv_radius; + + mediump vec3 direction; + highp float size; + + mediump vec3 color; + mediump float attenuation; + + mediump float cone_attenuation; + mediump float cone_angle; + mediump float specular_amount; + mediump float shadow_opacity; + + lowp vec3 pad; + lowp uint bake_mode; +}; + +#if !defined(DISABLE_LIGHT_OMNI) || defined(ADDITIVE_OMNI) +layout(std140) uniform OmniLightData { // ubo:5 + LightData omni_lights[MAX_LIGHT_DATA_STRUCTS]; +}; +#ifdef BASE_PASS +uniform uint omni_light_indices[MAX_FORWARD_LIGHTS]; +uniform uint omni_light_count; +#endif // BASE_PASS +#endif // DISABLE_LIGHT_OMNI + +#if !defined(DISABLE_LIGHT_SPOT) || defined(ADDITIVE_SPOT) +layout(std140) uniform SpotLightData { // ubo:6 + LightData spot_lights[MAX_LIGHT_DATA_STRUCTS]; +}; +#ifdef BASE_PASS +uniform uint spot_light_indices[MAX_FORWARD_LIGHTS]; +uniform uint spot_light_count; +#endif // BASE_PASS +#endif // DISABLE_LIGHT_SPOT +#endif // !defined(DISABLE_LIGHT_OMNI) || !defined(DISABLE_LIGHT_SPOT) || (defined(ADDITIVE_OMNI) || defined(ADDITIVE_SPOT) && defined(USE_ADDITIVE_LIGHTING)) + +#ifdef USE_ADDITIVE_LIGHTING +#ifdef ADDITIVE_OMNI +uniform lowp uint omni_light_index; +#endif +#ifdef ADDITIVE_SPOT +uniform lowp uint spot_light_index; +#endif +#endif // USE_ADDITIVE_LIGHTING + +#if !defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED) && defined(USE_VERTEX_LIGHTING) + +// Eyeballed approximation of `exp2(15.0 * (1.0 - roughness) + 1.0) * 0.25`. +// Uses slightly more FMA instructions (2x rate) to avoid special instructions (0.25x rate). +// Range is reduced to [0.64,4977] from [068,2,221,528] which makes mediump feasible for the rest of the shader. +mediump float roughness_to_shininess(mediump float roughness) { + mediump float r = 1.2 - roughness; + mediump float r2 = r * r; + return r * r2 * r2 * 2000.0; +} + +void light_compute(vec3 N, vec3 L, vec3 V, vec3 light_color, bool is_directional, float roughness, + inout vec3 diffuse_light, inout vec3 specular_light) { + float NdotL = min(dot(N, L), 1.0); + float cNdotL = max(NdotL, 0.0); // clamped NdotL + +#if defined(DIFFUSE_LAMBERT_WRAP) + // Energy conserving lambert wrap shader. + // https://web.archive.org/web/20210228210901/http://blog.stevemcauley.com/2011/12/03/energy-conserving-wrapped-diffuse/ + float diffuse_brdf_NL = max(0.0, (cNdotL + roughness) / ((1.0 + roughness) * (1.0 + roughness))) * (1.0 / M_PI); +#else + // lambert + float diffuse_brdf_NL = cNdotL * (1.0 / M_PI); +#endif + + diffuse_light += light_color * diffuse_brdf_NL; + +#if !defined(SPECULAR_DISABLED) + float specular_brdf_NL = 0.0; + // Normalized blinn always unless disabled. + vec3 H = normalize(V + L); + float cNdotH = clamp(dot(N, H), 0.0, 1.0); + float shininess = roughness_to_shininess(roughness); + float blinn = pow(cNdotH, shininess); + blinn *= (shininess + 2.0) * (1.0 / (8.0 * M_PI)) * cNdotL; + specular_brdf_NL = blinn; + specular_light += specular_brdf_NL * light_color; +#endif +} + +float get_omni_spot_attenuation(float distance, float inv_range, float decay) { + float nd = distance * inv_range; + nd *= nd; + nd *= nd; // nd^4 + nd = max(1.0 - nd, 0.0); + nd *= nd; // nd^2 + return nd * pow(max(distance, 0.0001), -decay); +} + +#if !defined(DISABLE_LIGHT_OMNI) || (defined(ADDITIVE_OMNI) && defined(USE_ADDITIVE_LIGHTING)) +void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, float roughness, + inout vec3 diffuse_light, inout vec3 specular_light) { + vec3 light_rel_vec = omni_lights[idx].position - vertex; + float light_length = length(light_rel_vec); + float omni_attenuation = get_omni_spot_attenuation(light_length, omni_lights[idx].inv_radius, omni_lights[idx].attenuation); + vec3 color = omni_lights[idx].color * omni_attenuation; // No light shaders here, so combine. + + light_compute(normal, normalize(light_rel_vec), eye_vec, color, false, roughness, + diffuse_light, + specular_light); +} +#endif // !defined(DISABLE_LIGHT_OMNI) || (defined(ADDITIVE_OMNI) && defined(USE_ADDITIVE_LIGHTING)) + +#if !defined(DISABLE_LIGHT_SPOT) || (defined(ADDITIVE_SPOT) && defined(USE_ADDITIVE_LIGHTING)) +void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, float roughness, + inout vec3 diffuse_light, + inout vec3 specular_light) { + vec3 light_rel_vec = spot_lights[idx].position - vertex; + float light_length = length(light_rel_vec); + float spot_attenuation = get_omni_spot_attenuation(light_length, spot_lights[idx].inv_radius, spot_lights[idx].attenuation); + vec3 spot_dir = spot_lights[idx].direction; + float scos = max(dot(-normalize(light_rel_vec), spot_dir), spot_lights[idx].cone_angle); + float spot_rim = max(0.0001, (1.0 - scos) / (1.0 - spot_lights[idx].cone_angle)); + + mediump float cone_attenuation = spot_lights[idx].cone_attenuation; + spot_attenuation *= 1.0 - pow(spot_rim, cone_attenuation); + + vec3 color = spot_lights[idx].color * spot_attenuation; + + light_compute(normal, normalize(light_rel_vec), eye_vec, color, false, roughness, + diffuse_light, specular_light); +} +#endif // !defined(DISABLE_LIGHT_SPOT) || (defined(ADDITIVE_SPOT) && defined(USE_ADDITIVE_LIGHTING)) + +#endif // !defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED) && defined(USE_VERTEX_LIGHTING) + +#endif // USE_VERTEX_LIGHTING + #ifdef USE_MULTIVIEW layout(std140) uniform MultiviewData { // ubo:8 highp mat4 projection_matrix_view[MAX_VIEWS]; @@ -540,8 +709,65 @@ void main() { gl_Position.z = 0.00001; gl_Position.w = 1.0; #endif -} +#ifdef USE_VERTEX_LIGHTING +#if !defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED) +#ifdef USE_MULTIVIEW + vec3 view = -normalize(vertex_interp - eye_offset); +#else + vec3 view = -normalize(vertex_interp); +#endif + diffuse_light_interp = vec3(0.0); + specular_light_interp = vec3(0.0); +#ifdef BASE_PASS +#ifndef DISABLE_LIGHT_DIRECTIONAL + for (uint i = uint(0); i < scene_data.directional_light_count; i++) { + light_compute(normal_interp, normalize(directional_lights[i].direction), normalize(view), directional_lights[i].color * directional_lights[i].energy, true, roughness, + diffuse_light_interp.rgb, + specular_light_interp.rgb); + } +#endif // !DISABLE_LIGHT_DIRECTIONAL + +#ifndef DISABLE_LIGHT_OMNI + for (uint i = 0u; i < omni_light_count; i++) { + light_process_omni(omni_light_indices[i], vertex_interp, view, normal_interp, roughness, + diffuse_light_interp.rgb, specular_light_interp.rgb); + } +#endif // !DISABLE_LIGHT_OMNI + +#ifndef DISABLE_LIGHT_SPOT + for (uint i = 0u; i < spot_light_count; i++) { + light_process_spot(spot_light_indices[i], vertex_interp, view, normal_interp, roughness, + diffuse_light_interp.rgb, specular_light_interp.rgb); + } +#endif // !DISABLE_LIGHT_SPOT +#endif // BASE_PASS + +/* ADDITIVE LIGHTING PASS */ +#ifdef USE_ADDITIVE_LIGHTING + additive_diffuse_light_interp = vec3(0.0); + additive_specular_light_interp = vec3(0.0); +#if !defined(ADDITIVE_OMNI) && !defined(ADDITIVE_SPOT) + + light_compute(normal_interp, normalize(directional_lights[directional_shadow_index].direction), normalize(view), directional_lights[directional_shadow_index].color * directional_lights[directional_shadow_index].energy, true, roughness, + additive_diffuse_light_interp.rgb, + additive_specular_light_interp.rgb); +#endif // !defined(ADDITIVE_OMNI) && !defined(ADDITIVE_SPOT) + +#ifdef ADDITIVE_OMNI + light_process_omni(omni_light_index, vertex_interp, view, normal_interp, roughness, + additive_diffuse_light_interp.rgb, additive_specular_light_interp.rgb); +#endif // ADDITIVE_OMNI + +#ifdef ADDITIVE_SPOT + light_process_spot(spot_light_index, vertex_interp, view, normal_interp, roughness, + additive_diffuse_light_interp.rgb, additive_specular_light_interp.rgb); +#endif // ADDITIVE_SPOT + +#endif // USE_ADDITIVE_LIGHTING +#endif // !defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED) +#endif // USE_VERTEX_LIGHTING +} /* clang-format off */ #[fragment] @@ -758,6 +984,16 @@ multiview_data; #define LIGHT_BAKE_DYNAMIC 2u #ifndef MODE_RENDER_DEPTH +#ifdef USE_VERTEX_LIGHTING +in vec3 diffuse_light_interp; +in vec3 specular_light_interp; + +#ifdef USE_ADDITIVE_LIGHTING +in vec3 additive_diffuse_light_interp; +in vec3 additive_specular_light_interp; +#endif // USE_ADDITIVE_LIGHTING +#endif // USE_VERTEX_LIGHTING + // Directional light data. #if !defined(DISABLE_LIGHT_DIRECTIONAL) || (!defined(ADDITIVE_OMNI) && !defined(ADDITIVE_SPOT)) @@ -809,22 +1045,22 @@ struct LightData { // This structure needs to be as packed as possible. layout(std140) uniform OmniLightData { // ubo:5 LightData omni_lights[MAX_LIGHT_DATA_STRUCTS]; }; -#ifdef BASE_PASS +#if defined(BASE_PASS) && !defined(USE_VERTEX_LIGHTING) uniform uint omni_light_indices[MAX_FORWARD_LIGHTS]; uniform uint omni_light_count; -#endif // BASE_PASS -#endif // DISABLE_LIGHT_OMNI +#endif // defined(BASE_PASS) && !defined(USE_VERTEX_LIGHTING) +#endif // !defined(DISABLE_LIGHT_OMNI) || defined(ADDITIVE_OMNI) #if !defined(DISABLE_LIGHT_SPOT) || defined(ADDITIVE_SPOT) layout(std140) uniform SpotLightData { // ubo:6 LightData spot_lights[MAX_LIGHT_DATA_STRUCTS]; }; -#ifdef BASE_PASS +#if defined(BASE_PASS) && !defined(USE_VERTEX_LIGHTING) uniform uint spot_light_indices[MAX_FORWARD_LIGHTS]; uniform uint spot_light_count; -#endif // BASE_PASS -#endif // DISABLE_LIGHT_SPOT -#endif // !defined(DISABLE_LIGHT_OMNI) || !defined(DISABLE_LIGHT_SPOT) +#endif // defined(BASE_PASS) && !defined(USE_VERTEX_LIGHTING) +#endif // !defined(DISABLE_LIGHT_SPOT) || defined(ADDITIVE_SPOT) +#endif // !defined(DISABLE_LIGHT_OMNI) || !defined(DISABLE_LIGHT_SPOT) || defined(ADDITIVE_OMNI) || defined(ADDITIVE_SPOT) #ifdef USE_ADDITIVE_LIGHTING #ifdef ADDITIVE_OMNI @@ -985,6 +1221,8 @@ vec3 F0(float metallic, float specular, vec3 albedo) { return mix(vec3(dielectric), albedo, vec3(metallic)); } #ifndef MODE_RENDER_DEPTH + +#ifndef USE_VERTEX_LIGHTING #if !defined(DISABLE_LIGHT_DIRECTIONAL) || !defined(DISABLE_LIGHT_OMNI) || !defined(DISABLE_LIGHT_SPOT) || defined(USE_ADDITIVE_LIGHTING) float D_GGX(float cos_theta_m, float alpha) { @@ -1284,6 +1522,7 @@ void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 f #endif // !defined(DISABLE_LIGHT_SPOT) || defined(ADDITIVE_SPOT) #endif // !defined(DISABLE_LIGHT_DIRECTIONAL) || !defined(DISABLE_LIGHT_OMNI) || !defined(DISABLE_LIGHT_SPOT) +#endif // !USE_VERTEX_LIGHTING vec4 fog_process(vec3 vertex) { vec3 fog_color = scene_data.fog_light_color; @@ -1859,9 +2098,13 @@ void main() { specular_light *= env.x * f0 + env.y * clamp(50.0 * f0.g, metallic, 1.0); #endif } - #endif // !AMBIENT_LIGHT_DISABLED +#ifdef USE_VERTEX_LIGHTING + specular_light += specular_light_interp * f0; + diffuse_light += diffuse_light_interp; +#else + #ifndef DISABLE_LIGHT_DIRECTIONAL for (uint i = uint(0); i < scene_data.directional_light_count; i++) { #if defined(USE_LIGHTMAP) && !defined(DISABLE_LIGHTMAP) @@ -1944,6 +2187,7 @@ void main() { diffuse_light, specular_light); } #endif // !DISABLE_LIGHT_SPOT +#endif // !USE_VERTEX_LIGHTING #endif // BASE_PASS #endif // !MODE_UNSHADED @@ -1993,7 +2237,6 @@ void main() { #else diffuse_light *= albedo; - diffuse_light *= 1.0 - metallic; ambient_light *= 1.0 - metallic; @@ -2024,6 +2267,11 @@ void main() { diffuse_light = vec3(0.0); specular_light = vec3(0.0); +#ifdef USE_VERTEX_LIGHTING + diffuse_light = additive_diffuse_light_interp; + specular_light = additive_specular_light_interp * f0; +#endif // USE_VERTEX_LIGHTING + #if !defined(ADDITIVE_OMNI) && !defined(ADDITIVE_SPOT) #ifndef SHADOWS_DISABLED @@ -2137,6 +2385,8 @@ void main() { #else float directional_shadow = 1.0f; #endif // SHADOWS_DISABLED + +#ifndef USE_VERTEX_LIGHTING light_compute(normal, normalize(directional_lights[directional_shadow_index].direction), normalize(view), directional_lights[directional_shadow_index].size, directional_lights[directional_shadow_index].color * directional_lights[directional_shadow_index].energy, true, directional_shadow, f0, roughness, metallic, 1.0, albedo, alpha, #ifdef LIGHT_BACKLIGHT_USED backlight, @@ -2153,6 +2403,11 @@ void main() { #endif diffuse_light, specular_light); +#else + // Just apply shadows to vertex lighting. + diffuse_light *= directional_shadow; + specular_light *= directional_shadow; +#endif // !USE_VERTEX_LIGHTING #endif // !defined(ADDITIVE_OMNI) && !defined(ADDITIVE_SPOT) #ifdef ADDITIVE_OMNI @@ -2162,6 +2417,8 @@ void main() { omni_shadow = texture(omni_shadow_texture, vec4(light_ray, 1.0 - length(light_ray) * omni_lights[omni_light_index].inv_radius)); omni_shadow = mix(1.0, omni_shadow, omni_lights[omni_light_index].shadow_opacity); #endif // SHADOWS_DISABLED + +#ifndef USE_VERTEX_LIGHTING light_process_omni(omni_light_index, vertex, view, normal, f0, roughness, metallic, omni_shadow, albedo, alpha, #ifdef LIGHT_BACKLIGHT_USED backlight, @@ -2177,6 +2434,11 @@ void main() { binormal, tangent, anisotropy, #endif diffuse_light, specular_light); +#else + // Just apply shadows to vertex lighting. + diffuse_light *= omni_shadow; + specular_light *= omni_shadow; +#endif // !USE_VERTEX_LIGHTING #endif // ADDITIVE_OMNI #ifdef ADDITIVE_SPOT @@ -2185,6 +2447,8 @@ void main() { spot_shadow = sample_shadow(spot_shadow_texture, positional_shadows[positional_shadow_index].shadow_atlas_pixel_size, shadow_coord); spot_shadow = mix(1.0, spot_shadow, spot_lights[spot_light_index].shadow_opacity); #endif // SHADOWS_DISABLED + +#ifndef USE_VERTEX_LIGHTING light_process_spot(spot_light_index, vertex, view, normal, f0, roughness, metallic, spot_shadow, albedo, alpha, #ifdef LIGHT_BACKLIGHT_USED backlight, @@ -2201,6 +2465,11 @@ void main() { binormal, anisotropy, #endif diffuse_light, specular_light); +#else + // Just apply shadows to vertex lighting. + diffuse_light *= spot_shadow; + specular_light *= spot_shadow; +#endif // !USE_VERTEX_LIGHTING #endif // ADDITIVE_SPOT diff --git a/drivers/gles3/storage/config.cpp b/drivers/gles3/storage/config.cpp index 0100719151..209b7dd7d2 100644 --- a/drivers/gles3/storage/config.cpp +++ b/drivers/gles3/storage/config.cpp @@ -178,7 +178,7 @@ Config::Config() { } #endif - force_vertex_shading = false; //GLOBAL_GET("rendering/quality/shading/force_vertex_shading"); + force_vertex_shading = GLOBAL_GET("rendering/shading/overrides/force_vertex_shading"); use_nearest_mip_filter = GLOBAL_GET("rendering/textures/default_filters/use_nearest_mipmap_filter"); use_depth_prepass = bool(GLOBAL_GET("rendering/driver/depth_prepass/enable")); diff --git a/drivers/gles3/storage/material_storage.cpp b/drivers/gles3/storage/material_storage.cpp index c29c741c2a..5dca149d99 100644 --- a/drivers/gles3/storage/material_storage.cpp +++ b/drivers/gles3/storage/material_storage.cpp @@ -1368,6 +1368,10 @@ MaterialStorage::MaterialStorage() { actions.render_mode_defines["ambient_light_disabled"] = "#define AMBIENT_LIGHT_DISABLED\n"; actions.render_mode_defines["shadow_to_opacity"] = "#define USE_SHADOW_TO_OPACITY\n"; actions.render_mode_defines["unshaded"] = "#define MODE_UNSHADED\n"; + if (!GLES3::Config::get_singleton()->force_vertex_shading) { + // If forcing vertex shading, this will be defined already. + actions.render_mode_defines["vertex_lighting"] = "#define USE_VERTEX_LIGHTING\n"; + } actions.render_mode_defines["fog_disabled"] = "#define FOG_DISABLED\n"; actions.default_filter = ShaderLanguage::FILTER_LINEAR_MIPMAP; diff --git a/editor/editor_file_system.h b/editor/editor_file_system.h index 255eaff10d..7aa0137f4e 100644 --- a/editor/editor_file_system.h +++ b/editor/editor_file_system.h @@ -114,9 +114,9 @@ class EditorFileSystemImportFormatSupportQuery : public RefCounted { GDCLASS(EditorFileSystemImportFormatSupportQuery, RefCounted); protected: - GDVIRTUAL0RC(bool, _is_active) - GDVIRTUAL0RC(Vector<String>, _get_file_extensions) - GDVIRTUAL0RC(bool, _query) + GDVIRTUAL0RC_REQUIRED(bool, _is_active) + GDVIRTUAL0RC_REQUIRED(Vector<String>, _get_file_extensions) + GDVIRTUAL0RC_REQUIRED(bool, _query) static void _bind_methods() { GDVIRTUAL_BIND(_is_active); GDVIRTUAL_BIND(_get_file_extensions); @@ -126,17 +126,17 @@ protected: public: virtual bool is_active() const { bool ret = false; - GDVIRTUAL_REQUIRED_CALL(_is_active, ret); + GDVIRTUAL_CALL(_is_active, ret); return ret; } virtual Vector<String> get_file_extensions() const { Vector<String> ret; - GDVIRTUAL_REQUIRED_CALL(_get_file_extensions, ret); + GDVIRTUAL_CALL(_get_file_extensions, ret); return ret; } virtual bool query() { bool ret = false; - GDVIRTUAL_REQUIRED_CALL(_query, ret); + GDVIRTUAL_CALL(_query, ret); return ret; } }; diff --git a/editor/editor_script.cpp b/editor/editor_script.cpp index 30a4b6811c..6968c7f25a 100644 --- a/editor/editor_script.cpp +++ b/editor/editor_script.cpp @@ -78,7 +78,7 @@ EditorInterface *EditorScript::get_editor_interface() const { } void EditorScript::run() { - GDVIRTUAL_REQUIRED_CALL(_run); + GDVIRTUAL_CALL(_run); } void EditorScript::_bind_methods() { diff --git a/editor/editor_script.h b/editor/editor_script.h index 72e7641df7..b0724c31c0 100644 --- a/editor/editor_script.h +++ b/editor/editor_script.h @@ -44,7 +44,7 @@ class EditorScript : public RefCounted { protected: static void _bind_methods(); - GDVIRTUAL0(_run) + GDVIRTUAL0_REQUIRED(_run) public: void add_root_node(Node *p_node); diff --git a/editor/editor_vcs_interface.cpp b/editor/editor_vcs_interface.cpp index f4745b8730..6a5d49e41a 100644 --- a/editor/editor_vcs_interface.cpp +++ b/editor/editor_vcs_interface.cpp @@ -41,17 +41,17 @@ void EditorVCSInterface::popup_error(const String &p_msg) { bool EditorVCSInterface::initialize(const String &p_project_path) { bool result = false; - GDVIRTUAL_REQUIRED_CALL(_initialize, p_project_path, result); + GDVIRTUAL_CALL(_initialize, p_project_path, result); return result; } void EditorVCSInterface::set_credentials(const String &p_username, const String &p_password, const String &p_ssh_public_key, const String &p_ssh_private_key, const String &p_ssh_passphrase) { - GDVIRTUAL_REQUIRED_CALL(_set_credentials, p_username, p_password, p_ssh_public_key, p_ssh_private_key, p_ssh_passphrase); + GDVIRTUAL_CALL(_set_credentials, p_username, p_password, p_ssh_public_key, p_ssh_private_key, p_ssh_passphrase); } List<String> EditorVCSInterface::get_remotes() { TypedArray<String> result; - if (!GDVIRTUAL_REQUIRED_CALL(_get_remotes, result)) { + if (!GDVIRTUAL_CALL(_get_remotes, result)) { return {}; } @@ -64,7 +64,7 @@ List<String> EditorVCSInterface::get_remotes() { List<EditorVCSInterface::StatusFile> EditorVCSInterface::get_modified_files_data() { TypedArray<Dictionary> result; - if (!GDVIRTUAL_REQUIRED_CALL(_get_modified_files_data, result)) { + if (!GDVIRTUAL_CALL(_get_modified_files_data, result)) { return {}; } @@ -76,24 +76,24 @@ List<EditorVCSInterface::StatusFile> EditorVCSInterface::get_modified_files_data } void EditorVCSInterface::stage_file(const String &p_file_path) { - GDVIRTUAL_REQUIRED_CALL(_stage_file, p_file_path); + GDVIRTUAL_CALL(_stage_file, p_file_path); } void EditorVCSInterface::unstage_file(const String &p_file_path) { - GDVIRTUAL_REQUIRED_CALL(_unstage_file, p_file_path); + GDVIRTUAL_CALL(_unstage_file, p_file_path); } void EditorVCSInterface::discard_file(const String &p_file_path) { - GDVIRTUAL_REQUIRED_CALL(_discard_file, p_file_path); + GDVIRTUAL_CALL(_discard_file, p_file_path); } void EditorVCSInterface::commit(const String &p_msg) { - GDVIRTUAL_REQUIRED_CALL(_commit, p_msg); + GDVIRTUAL_CALL(_commit, p_msg); } List<EditorVCSInterface::DiffFile> EditorVCSInterface::get_diff(const String &p_identifier, TreeArea p_area) { TypedArray<Dictionary> result; - if (!GDVIRTUAL_REQUIRED_CALL(_get_diff, p_identifier, int(p_area), result)) { + if (!GDVIRTUAL_CALL(_get_diff, p_identifier, int(p_area), result)) { return {}; } @@ -106,7 +106,7 @@ List<EditorVCSInterface::DiffFile> EditorVCSInterface::get_diff(const String &p_ List<EditorVCSInterface::Commit> EditorVCSInterface::get_previous_commits(int p_max_commits) { TypedArray<Dictionary> result; - if (!GDVIRTUAL_REQUIRED_CALL(_get_previous_commits, p_max_commits, result)) { + if (!GDVIRTUAL_CALL(_get_previous_commits, p_max_commits, result)) { return {}; } @@ -119,7 +119,7 @@ List<EditorVCSInterface::Commit> EditorVCSInterface::get_previous_commits(int p_ List<String> EditorVCSInterface::get_branch_list() { TypedArray<String> result; - if (!GDVIRTUAL_REQUIRED_CALL(_get_branch_list, result)) { + if (!GDVIRTUAL_CALL(_get_branch_list, result)) { return {}; } @@ -131,48 +131,48 @@ List<String> EditorVCSInterface::get_branch_list() { } void EditorVCSInterface::create_branch(const String &p_branch_name) { - GDVIRTUAL_REQUIRED_CALL(_create_branch, p_branch_name); + GDVIRTUAL_CALL(_create_branch, p_branch_name); } void EditorVCSInterface::create_remote(const String &p_remote_name, const String &p_remote_url) { - GDVIRTUAL_REQUIRED_CALL(_create_remote, p_remote_name, p_remote_url); + GDVIRTUAL_CALL(_create_remote, p_remote_name, p_remote_url); } void EditorVCSInterface::remove_branch(const String &p_branch_name) { - GDVIRTUAL_REQUIRED_CALL(_remove_branch, p_branch_name); + GDVIRTUAL_CALL(_remove_branch, p_branch_name); } void EditorVCSInterface::remove_remote(const String &p_remote_name) { - GDVIRTUAL_REQUIRED_CALL(_remove_remote, p_remote_name); + GDVIRTUAL_CALL(_remove_remote, p_remote_name); } String EditorVCSInterface::get_current_branch_name() { String result; - GDVIRTUAL_REQUIRED_CALL(_get_current_branch_name, result); + GDVIRTUAL_CALL(_get_current_branch_name, result); return result; } bool EditorVCSInterface::checkout_branch(const String &p_branch_name) { bool result = false; - GDVIRTUAL_REQUIRED_CALL(_checkout_branch, p_branch_name, result); + GDVIRTUAL_CALL(_checkout_branch, p_branch_name, result); return result; } void EditorVCSInterface::pull(const String &p_remote) { - GDVIRTUAL_REQUIRED_CALL(_pull, p_remote); + GDVIRTUAL_CALL(_pull, p_remote); } void EditorVCSInterface::push(const String &p_remote, bool p_force) { - GDVIRTUAL_REQUIRED_CALL(_push, p_remote, p_force); + GDVIRTUAL_CALL(_push, p_remote, p_force); } void EditorVCSInterface::fetch(const String &p_remote) { - GDVIRTUAL_REQUIRED_CALL(_fetch, p_remote); + GDVIRTUAL_CALL(_fetch, p_remote); } List<EditorVCSInterface::DiffHunk> EditorVCSInterface::get_line_diff(const String &p_file_path, const String &p_text) { TypedArray<Dictionary> result; - if (!GDVIRTUAL_REQUIRED_CALL(_get_line_diff, p_file_path, p_text, result)) { + if (!GDVIRTUAL_CALL(_get_line_diff, p_file_path, p_text, result)) { return {}; } @@ -185,13 +185,13 @@ List<EditorVCSInterface::DiffHunk> EditorVCSInterface::get_line_diff(const Strin bool EditorVCSInterface::shut_down() { bool result = false; - GDVIRTUAL_REQUIRED_CALL(_shut_down, result); + GDVIRTUAL_CALL(_shut_down, result); return result; } String EditorVCSInterface::get_vcs_name() { String result; - GDVIRTUAL_REQUIRED_CALL(_get_vcs_name, result); + GDVIRTUAL_CALL(_get_vcs_name, result); return result; } diff --git a/editor/editor_vcs_interface.h b/editor/editor_vcs_interface.h index 8fcd45756a..a425682bed 100644 --- a/editor/editor_vcs_interface.h +++ b/editor/editor_vcs_interface.h @@ -106,29 +106,29 @@ protected: StatusFile _convert_status_file(const Dictionary &p_status_file); // Proxy endpoints for extensions to implement - GDVIRTUAL1R(bool, _initialize, String); - GDVIRTUAL5(_set_credentials, String, String, String, String, String); - GDVIRTUAL0R(TypedArray<Dictionary>, _get_modified_files_data); - GDVIRTUAL1(_stage_file, String); - GDVIRTUAL1(_unstage_file, String); - GDVIRTUAL1(_discard_file, String); - GDVIRTUAL1(_commit, String); - GDVIRTUAL2R(TypedArray<Dictionary>, _get_diff, String, int); - GDVIRTUAL0R(bool, _shut_down); - GDVIRTUAL0R(String, _get_vcs_name); - GDVIRTUAL1R(TypedArray<Dictionary>, _get_previous_commits, int); - GDVIRTUAL0R(TypedArray<String>, _get_branch_list); - GDVIRTUAL0R(TypedArray<String>, _get_remotes); - GDVIRTUAL1(_create_branch, String); - GDVIRTUAL1(_remove_branch, String); - GDVIRTUAL2(_create_remote, String, String); - GDVIRTUAL1(_remove_remote, String); - GDVIRTUAL0R(String, _get_current_branch_name); - GDVIRTUAL1R(bool, _checkout_branch, String); - GDVIRTUAL1(_pull, String); - GDVIRTUAL2(_push, String, bool); - GDVIRTUAL1(_fetch, String); - GDVIRTUAL2R(TypedArray<Dictionary>, _get_line_diff, String, String); + GDVIRTUAL1R_REQUIRED(bool, _initialize, String); + GDVIRTUAL5_REQUIRED(_set_credentials, String, String, String, String, String); + GDVIRTUAL0R_REQUIRED(TypedArray<Dictionary>, _get_modified_files_data); + GDVIRTUAL1_REQUIRED(_stage_file, String); + GDVIRTUAL1_REQUIRED(_unstage_file, String); + GDVIRTUAL1_REQUIRED(_discard_file, String); + GDVIRTUAL1_REQUIRED(_commit, String); + GDVIRTUAL2R_REQUIRED(TypedArray<Dictionary>, _get_diff, String, int); + GDVIRTUAL0R_REQUIRED(bool, _shut_down); + GDVIRTUAL0R_REQUIRED(String, _get_vcs_name); + GDVIRTUAL1R_REQUIRED(TypedArray<Dictionary>, _get_previous_commits, int); + GDVIRTUAL0R_REQUIRED(TypedArray<String>, _get_branch_list); + GDVIRTUAL0R_REQUIRED(TypedArray<String>, _get_remotes); + GDVIRTUAL1_REQUIRED(_create_branch, String); + GDVIRTUAL1_REQUIRED(_remove_branch, String); + GDVIRTUAL2_REQUIRED(_create_remote, String, String); + GDVIRTUAL1_REQUIRED(_remove_remote, String); + GDVIRTUAL0R_REQUIRED(String, _get_current_branch_name); + GDVIRTUAL1R_REQUIRED(bool, _checkout_branch, String); + GDVIRTUAL1_REQUIRED(_pull, String); + GDVIRTUAL2_REQUIRED(_push, String, bool); + GDVIRTUAL1_REQUIRED(_fetch, String); + GDVIRTUAL2R_REQUIRED(TypedArray<Dictionary>, _get_line_diff, String, String); public: static EditorVCSInterface *get_singleton(); diff --git a/editor/export/editor_export_platform_extension.cpp b/editor/export/editor_export_platform_extension.cpp index 5b75ff19a4..b4f338437f 100644 --- a/editor/export/editor_export_platform_extension.cpp +++ b/editor/export/editor_export_platform_extension.cpp @@ -81,7 +81,7 @@ void EditorExportPlatformExtension::_bind_methods() { void EditorExportPlatformExtension::get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) const { Vector<String> ret; - if (GDVIRTUAL_REQUIRED_CALL(_get_preset_features, p_preset, ret) && r_features) { + if (GDVIRTUAL_CALL(_get_preset_features, p_preset, ret) && r_features) { for (const String &E : ret) { r_features->push_back(E); } @@ -144,19 +144,19 @@ String EditorExportPlatformExtension::get_export_option_warning(const EditorExpo String EditorExportPlatformExtension::get_os_name() const { String ret; - GDVIRTUAL_REQUIRED_CALL(_get_os_name, ret); + GDVIRTUAL_CALL(_get_os_name, ret); return ret; } String EditorExportPlatformExtension::get_name() const { String ret; - GDVIRTUAL_REQUIRED_CALL(_get_name, ret); + GDVIRTUAL_CALL(_get_name, ret); return ret; } Ref<Texture2D> EditorExportPlatformExtension::get_logo() const { Ref<Texture2D> ret; - GDVIRTUAL_REQUIRED_CALL(_get_logo, ret); + GDVIRTUAL_CALL(_get_logo, ret); return ret; } @@ -238,7 +238,7 @@ bool EditorExportPlatformExtension::has_valid_export_configuration(const Ref<Edi bool ret = false; config_error = r_error; config_missing_templates = r_missing_templates; - if (GDVIRTUAL_REQUIRED_CALL(_has_valid_export_configuration, p_preset, p_debug, ret)) { + if (GDVIRTUAL_CALL(_has_valid_export_configuration, p_preset, p_debug, ret)) { r_error = config_error; r_missing_templates = config_missing_templates; } @@ -248,7 +248,7 @@ bool EditorExportPlatformExtension::has_valid_export_configuration(const Ref<Edi bool EditorExportPlatformExtension::has_valid_project_configuration(const Ref<EditorExportPreset> &p_preset, String &r_error) const { bool ret = false; config_error = r_error; - if (GDVIRTUAL_REQUIRED_CALL(_has_valid_project_configuration, p_preset, ret)) { + if (GDVIRTUAL_CALL(_has_valid_project_configuration, p_preset, ret)) { r_error = config_error; } return ret; @@ -257,7 +257,7 @@ bool EditorExportPlatformExtension::has_valid_project_configuration(const Ref<Ed List<String> EditorExportPlatformExtension::get_binary_extensions(const Ref<EditorExportPreset> &p_preset) const { List<String> ret_list; Vector<String> ret; - if (GDVIRTUAL_REQUIRED_CALL(_get_binary_extensions, p_preset, ret)) { + if (GDVIRTUAL_CALL(_get_binary_extensions, p_preset, ret)) { for (const String &E : ret) { ret_list.push_back(E); } @@ -269,7 +269,7 @@ Error EditorExportPlatformExtension::export_project(const Ref<EditorExportPreset ExportNotifier notifier(*this, p_preset, p_debug, p_path, p_flags); Error ret = FAILED; - GDVIRTUAL_REQUIRED_CALL(_export_project, p_preset, p_debug, p_path, p_flags, ret); + GDVIRTUAL_CALL(_export_project, p_preset, p_debug, p_path, p_flags, ret); return ret; } @@ -333,7 +333,7 @@ Error EditorExportPlatformExtension::export_zip_patch(const Ref<EditorExportPres void EditorExportPlatformExtension::get_platform_features(List<String> *r_features) const { Vector<String> ret; - if (GDVIRTUAL_REQUIRED_CALL(_get_platform_features, ret) && r_features) { + if (GDVIRTUAL_CALL(_get_platform_features, ret) && r_features) { for (const String &E : ret) { r_features->push_back(E); } diff --git a/editor/export/editor_export_platform_extension.h b/editor/export/editor_export_platform_extension.h index d1db922698..390aaf4590 100644 --- a/editor/export/editor_export_platform_extension.h +++ b/editor/export/editor_export_platform_extension.h @@ -45,7 +45,7 @@ protected: public: virtual void get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) const override; - GDVIRTUAL1RC(Vector<String>, _get_preset_features, Ref<EditorExportPreset>); + GDVIRTUAL1RC_REQUIRED(Vector<String>, _get_preset_features, Ref<EditorExportPreset>); virtual bool is_executable(const String &p_path) const override; GDVIRTUAL1RC(bool, _is_executable, const String &); @@ -63,13 +63,13 @@ public: GDVIRTUAL2RC(String, _get_export_option_warning, Ref<EditorExportPreset>, const StringName &); virtual String get_os_name() const override; - GDVIRTUAL0RC(String, _get_os_name); + GDVIRTUAL0RC_REQUIRED(String, _get_os_name); virtual String get_name() const override; - GDVIRTUAL0RC(String, _get_name); + GDVIRTUAL0RC_REQUIRED(String, _get_name); virtual Ref<Texture2D> get_logo() const override; - GDVIRTUAL0RC(Ref<Texture2D>, _get_logo); + GDVIRTUAL0RC_REQUIRED(Ref<Texture2D>, _get_logo); virtual bool poll_export() override; GDVIRTUAL0R(bool, _poll_export); @@ -119,16 +119,16 @@ public: GDVIRTUAL2RC(bool, _can_export, Ref<EditorExportPreset>, bool); virtual bool has_valid_export_configuration(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates, bool p_debug = false) const override; - GDVIRTUAL2RC(bool, _has_valid_export_configuration, Ref<EditorExportPreset>, bool); + GDVIRTUAL2RC_REQUIRED(bool, _has_valid_export_configuration, Ref<EditorExportPreset>, bool); virtual bool has_valid_project_configuration(const Ref<EditorExportPreset> &p_preset, String &r_error) const override; - GDVIRTUAL1RC(bool, _has_valid_project_configuration, Ref<EditorExportPreset>); + GDVIRTUAL1RC_REQUIRED(bool, _has_valid_project_configuration, Ref<EditorExportPreset>); virtual List<String> get_binary_extensions(const Ref<EditorExportPreset> &p_preset) const override; - GDVIRTUAL1RC(Vector<String>, _get_binary_extensions, Ref<EditorExportPreset>); + GDVIRTUAL1RC_REQUIRED(Vector<String>, _get_binary_extensions, Ref<EditorExportPreset>); virtual Error export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, BitField<EditorExportPlatform::DebugFlags> p_flags = 0) override; - GDVIRTUAL4R(Error, _export_project, Ref<EditorExportPreset>, bool, const String &, BitField<EditorExportPlatform::DebugFlags>); + GDVIRTUAL4R_REQUIRED(Error, _export_project, Ref<EditorExportPreset>, bool, const String &, BitField<EditorExportPlatform::DebugFlags>); virtual Error export_pack(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, BitField<EditorExportPlatform::DebugFlags> p_flags = 0) override; GDVIRTUAL4R(Error, _export_pack, Ref<EditorExportPreset>, bool, const String &, BitField<EditorExportPlatform::DebugFlags>); @@ -143,7 +143,7 @@ public: GDVIRTUAL5R(Error, _export_zip_patch, Ref<EditorExportPreset>, bool, const String &, const Vector<String> &, BitField<EditorExportPlatform::DebugFlags>); virtual void get_platform_features(List<String> *r_features) const override; - GDVIRTUAL0RC(Vector<String>, _get_platform_features); + GDVIRTUAL0RC_REQUIRED(Vector<String>, _get_platform_features); virtual String get_debug_protocol() const override; GDVIRTUAL0RC(String, _get_debug_protocol); diff --git a/editor/export/editor_export_plugin.cpp b/editor/export/editor_export_plugin.cpp index 5945c02413..2f57010c2c 100644 --- a/editor/export/editor_export_plugin.cpp +++ b/editor/export/editor_export_plugin.cpp @@ -187,7 +187,7 @@ bool EditorExportPlugin::_begin_customize_resources(const Ref<EditorExportPlatfo Ref<Resource> EditorExportPlugin::_customize_resource(const Ref<Resource> &p_resource, const String &p_path) { Ref<Resource> ret; - GDVIRTUAL_REQUIRED_CALL(_customize_resource, p_resource, p_path, ret); + GDVIRTUAL_CALL(_customize_resource, p_resource, p_path, ret); return ret; } @@ -199,13 +199,13 @@ bool EditorExportPlugin::_begin_customize_scenes(const Ref<EditorExportPlatform> Node *EditorExportPlugin::_customize_scene(Node *p_root, const String &p_path) { Node *ret = nullptr; - GDVIRTUAL_REQUIRED_CALL(_customize_scene, p_root, p_path, ret); + GDVIRTUAL_CALL(_customize_scene, p_root, p_path, ret); return ret; } uint64_t EditorExportPlugin::_get_customization_configuration_hash() const { uint64_t ret = 0; - GDVIRTUAL_REQUIRED_CALL(_get_customization_configuration_hash, ret); + GDVIRTUAL_CALL(_get_customization_configuration_hash, ret); return ret; } @@ -219,7 +219,7 @@ void EditorExportPlugin::_end_customize_resources() { String EditorExportPlugin::get_name() const { String ret; - GDVIRTUAL_REQUIRED_CALL(_get_name, ret); + GDVIRTUAL_CALL(_get_name, ret); return ret; } diff --git a/editor/export/editor_export_plugin.h b/editor/export/editor_export_plugin.h index 4c0107af72..8c744b3108 100644 --- a/editor/export/editor_export_plugin.h +++ b/editor/export/editor_export_plugin.h @@ -119,11 +119,11 @@ protected: GDVIRTUAL0(_export_end) GDVIRTUAL2RC(bool, _begin_customize_resources, const Ref<EditorExportPlatform> &, const Vector<String> &) - GDVIRTUAL2R(Ref<Resource>, _customize_resource, const Ref<Resource> &, String) + GDVIRTUAL2R_REQUIRED(Ref<Resource>, _customize_resource, const Ref<Resource> &, String) GDVIRTUAL2RC(bool, _begin_customize_scenes, const Ref<EditorExportPlatform> &, const Vector<String> &) - GDVIRTUAL2R(Node *, _customize_scene, Node *, String) - GDVIRTUAL0RC(uint64_t, _get_customization_configuration_hash) + GDVIRTUAL2R_REQUIRED(Node *, _customize_scene, Node *, String) + GDVIRTUAL0RC_REQUIRED(uint64_t, _get_customization_configuration_hash) GDVIRTUAL0(_end_customize_scenes) GDVIRTUAL0(_end_customize_resources) @@ -134,7 +134,7 @@ protected: GDVIRTUAL1RC(bool, _should_update_export_options, const Ref<EditorExportPlatform> &); GDVIRTUAL2RC(String, _get_export_option_warning, const Ref<EditorExportPlatform> &, String); - GDVIRTUAL0RC(String, _get_name) + GDVIRTUAL0RC_REQUIRED(String, _get_name) GDVIRTUAL1RC(bool, _supports_platform, const Ref<EditorExportPlatform> &); diff --git a/editor/plugins/tool_button_editor_plugin.cpp b/editor/plugins/tool_button_editor_plugin.cpp new file mode 100644 index 0000000000..d9852c8694 --- /dev/null +++ b/editor/plugins/tool_button_editor_plugin.cpp @@ -0,0 +1,82 @@ +/**************************************************************************/ +/* tool_button_editor_plugin.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "tool_button_editor_plugin.h" + +#include "scene/gui/button.h" + +void EditorInspectorToolButtonPlugin::_update_action_icon(Button *p_action_button, const String &p_action_icon) { + p_action_button->set_icon(p_action_button->get_editor_theme_icon(p_action_icon)); +} + +void EditorInspectorToolButtonPlugin::_call_action(const Variant &p_object, const StringName &p_property) { + Object *object = p_object.get_validated_object(); + ERR_FAIL_NULL_MSG(object, vformat(R"(Failed to get property "%s" on a previously freed instance.)", p_property)); + + const Variant value = object->get(p_property); + ERR_FAIL_COND_MSG(value.get_type() != Variant::CALLABLE, vformat(R"(The value of property "%s" is %s, but Callable was expected.)", p_property, Variant::get_type_name(value.get_type()))); + + const Callable callable = value; + ERR_FAIL_COND_MSG(!callable.is_valid(), vformat(R"(Tool button action "%s" is an invalid callable.)", callable)); + + Variant ret; + Callable::CallError ce; + callable.callp(nullptr, 0, ret, ce); + ERR_FAIL_COND_MSG(ce.error != Callable::CallError::CALL_OK, vformat(R"(Error calling tool button action "%s": %s)", callable, Variant::get_call_error_text(callable.get_method(), nullptr, 0, ce))); +} + +bool EditorInspectorToolButtonPlugin::can_handle(Object *p_object) { + return true; +} + +bool EditorInspectorToolButtonPlugin::parse_property(Object *p_object, const Variant::Type p_type, const String &p_path, const PropertyHint p_hint, const String &p_hint_text, const BitField<PropertyUsageFlags> p_usage, const bool p_wide) { + if (p_type != Variant::CALLABLE || p_hint != PROPERTY_HINT_TOOL_BUTTON || !p_usage.has_flag(PROPERTY_USAGE_EDITOR)) { + return false; + } + + const PackedStringArray splits = p_hint_text.rsplit(",", true, 1); + const String &hint_text = splits[0]; // Safe since `splits` cannot be empty. + const String &hint_icon = splits.size() > 1 ? splits[1] : "Callable"; + + Button *action_button = EditorInspector::create_inspector_action_button(hint_text); + action_button->set_auto_translate_mode(Node::AUTO_TRANSLATE_MODE_DISABLED); + action_button->set_disabled(p_usage & PROPERTY_USAGE_READ_ONLY); + action_button->connect(SceneStringName(theme_changed), callable_mp(this, &EditorInspectorToolButtonPlugin::_update_action_icon).bind(action_button, hint_icon)); + action_button->connect(SceneStringName(pressed), callable_mp(this, &EditorInspectorToolButtonPlugin::_call_action).bind(p_object, p_path)); + + add_custom_control(action_button); + return true; +} + +ToolButtonEditorPlugin::ToolButtonEditorPlugin() { + Ref<EditorInspectorToolButtonPlugin> plugin; + plugin.instantiate(); + add_inspector_plugin(plugin); +} diff --git a/modules/squish/image_decompress_squish.cpp b/editor/plugins/tool_button_editor_plugin.h index 3841ba8db1..2d185c3a8f 100644 --- a/modules/squish/image_decompress_squish.cpp +++ b/editor/plugins/tool_button_editor_plugin.h @@ -1,5 +1,5 @@ /**************************************************************************/ -/* image_decompress_squish.cpp */ +/* tool_button_editor_plugin.h */ /**************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,69 +28,30 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#include "image_decompress_squish.h" +#ifndef TOOL_BUTTON_EDITOR_PLUGIN_H +#define TOOL_BUTTON_EDITOR_PLUGIN_H -#include <squish.h> +#include "editor/editor_inspector.h" +#include "editor/plugins/editor_plugin.h" -void image_decompress_squish(Image *p_image) { - int w = p_image->get_width(); - int h = p_image->get_height(); +class EditorInspectorToolButtonPlugin : public EditorInspectorPlugin { + GDCLASS(EditorInspectorToolButtonPlugin, EditorInspectorPlugin); - Image::Format source_format = p_image->get_format(); - Image::Format target_format = Image::FORMAT_RGBA8; + void _update_action_icon(Button *p_action_button, const String &p_action_icon); + void _call_action(const Variant &p_object, const StringName &p_property); - Vector<uint8_t> data; - int64_t target_size = Image::get_image_data_size(w, h, target_format, p_image->has_mipmaps()); - int mm_count = p_image->get_mipmap_count(); - data.resize(target_size); +public: + virtual bool can_handle(Object *p_object) override; + virtual bool parse_property(Object *p_object, const Variant::Type p_type, const String &p_path, const PropertyHint p_hint, const String &p_hint_text, const BitField<PropertyUsageFlags> p_usage, const bool p_wide = false) override; +}; - const uint8_t *rb = p_image->get_data().ptr(); - uint8_t *wb = data.ptrw(); +class ToolButtonEditorPlugin : public EditorPlugin { + GDCLASS(ToolButtonEditorPlugin, EditorPlugin); - int squish_flags = 0; +public: + virtual String get_name() const override { return "ToolButtonEditorPlugin"; } - switch (source_format) { - case Image::FORMAT_DXT1: - squish_flags = squish::kDxt1; - break; + ToolButtonEditorPlugin(); +}; - case Image::FORMAT_DXT3: - squish_flags = squish::kDxt3; - break; - - case Image::FORMAT_DXT5: - case Image::FORMAT_DXT5_RA_AS_RG: - squish_flags = squish::kDxt5; - break; - - case Image::FORMAT_RGTC_R: - squish_flags = squish::kBc4; - break; - - case Image::FORMAT_RGTC_RG: - squish_flags = squish::kBc5; - break; - - default: - ERR_FAIL_MSG("Squish: Can't decompress unknown format: " + itos(p_image->get_format()) + "."); - break; - } - - for (int i = 0; i <= mm_count; i++) { - int64_t src_ofs = 0, mipmap_size = 0; - int mipmap_w = 0, mipmap_h = 0; - p_image->get_mipmap_offset_size_and_dimensions(i, src_ofs, mipmap_size, mipmap_w, mipmap_h); - - int64_t dst_ofs = Image::get_image_mipmap_offset(p_image->get_width(), p_image->get_height(), target_format, i); - squish::DecompressImage(&wb[dst_ofs], w, h, &rb[src_ofs], squish_flags); - - w >>= 1; - h >>= 1; - } - - p_image->set_data(p_image->get_width(), p_image->get_height(), p_image->has_mipmaps(), target_format, data); - - if (source_format == Image::FORMAT_DXT5_RA_AS_RG) { - p_image->convert_ra_rgba8_to_rg(); - } -} +#endif // TOOL_BUTTON_EDITOR_PLUGIN_H diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp index f98a30ebb3..ede8351e41 100644 --- a/editor/plugins/visual_shader_editor_plugin.cpp +++ b/editor/plugins/visual_shader_editor_plugin.cpp @@ -6300,6 +6300,7 @@ VisualShaderEditor::VisualShaderEditor() { graph->connect("scroll_offset_changed", callable_mp(this, &VisualShaderEditor::_scroll_changed)); graph->connect("duplicate_nodes_request", callable_mp(this, &VisualShaderEditor::_duplicate_nodes)); graph->connect("copy_nodes_request", callable_mp(this, &VisualShaderEditor::_copy_nodes).bind(false)); + graph->connect("cut_nodes_request", callable_mp(this, &VisualShaderEditor::_copy_nodes).bind(true)); graph->connect("paste_nodes_request", callable_mp(this, &VisualShaderEditor::_paste_nodes).bind(false, Point2())); graph->connect("delete_nodes_request", callable_mp(this, &VisualShaderEditor::_delete_nodes_request)); graph->connect(SceneStringName(gui_input), callable_mp(this, &VisualShaderEditor::_graph_gui_input)); diff --git a/editor/project_manager/project_dialog.cpp b/editor/project_manager/project_dialog.cpp index 7acda16890..01868846bf 100644 --- a/editor/project_manager/project_dialog.cpp +++ b/editor/project_manager/project_dialog.cpp @@ -1024,8 +1024,14 @@ ProjectDialog::ProjectDialog() { add_child(fdialog_install); project_name->connect(SceneStringName(text_changed), callable_mp(this, &ProjectDialog::_project_name_changed).unbind(1)); + project_name->connect(SceneStringName(text_submitted), callable_mp(this, &ProjectDialog::ok_pressed).unbind(1)); + project_path->connect(SceneStringName(text_changed), callable_mp(this, &ProjectDialog::_project_path_changed).unbind(1)); + project_path->connect(SceneStringName(text_submitted), callable_mp(this, &ProjectDialog::ok_pressed).unbind(1)); + install_path->connect(SceneStringName(text_changed), callable_mp(this, &ProjectDialog::_install_path_changed).unbind(1)); + install_path->connect(SceneStringName(text_submitted), callable_mp(this, &ProjectDialog::ok_pressed).unbind(1)); + fdialog_install->connect("dir_selected", callable_mp(this, &ProjectDialog::_install_path_selected)); fdialog_install->connect("file_selected", callable_mp(this, &ProjectDialog::_install_path_selected)); diff --git a/editor/register_editor_types.cpp b/editor/register_editor_types.cpp index 00377a0dd2..19aeeb0612 100644 --- a/editor/register_editor_types.cpp +++ b/editor/register_editor_types.cpp @@ -127,6 +127,7 @@ #include "editor/plugins/texture_region_editor_plugin.h" #include "editor/plugins/theme_editor_plugin.h" #include "editor/plugins/tiles/tiles_editor_plugin.h" +#include "editor/plugins/tool_button_editor_plugin.h" #include "editor/plugins/version_control_editor_plugin.h" #include "editor/plugins/visual_shader_editor_plugin.h" #include "editor/plugins/voxel_gi_editor_plugin.h" @@ -247,6 +248,7 @@ void register_editor_types() { EditorPlugins::add_by_type<TextureLayeredEditorPlugin>(); EditorPlugins::add_by_type<TextureRegionEditorPlugin>(); EditorPlugins::add_by_type<ThemeEditorPlugin>(); + EditorPlugins::add_by_type<ToolButtonEditorPlugin>(); EditorPlugins::add_by_type<VoxelGIEditorPlugin>(); // 2D diff --git a/editor/renames_map_3_to_4.cpp b/editor/renames_map_3_to_4.cpp index ae7c86a5e5..ca5d3cbf2a 100644 --- a/editor/renames_map_3_to_4.cpp +++ b/editor/renames_map_3_to_4.cpp @@ -1354,7 +1354,6 @@ const char *RenamesMap3To4::project_settings_renames[][2] = { { "rendering/quality/shading/force_lambert_over_burley", "rendering/shading/overrides/force_lambert_over_burley" }, { "rendering/quality/shading/force_lambert_over_burley.mobile", "rendering/shading/overrides/force_lambert_over_burley.mobile" }, { "rendering/quality/shading/force_vertex_shading", "rendering/shading/overrides/force_vertex_shading" }, - { "rendering/quality/shading/force_vertex_shading.mobile", "rendering/shading/overrides/force_vertex_shading.mobile" }, { "rendering/quality/shadow_atlas/quadrant_0_subdiv", "rendering/lights_and_shadows/shadow_atlas/quadrant_0_subdiv" }, { "rendering/quality/shadow_atlas/quadrant_1_subdiv", "rendering/lights_and_shadows/shadow_atlas/quadrant_1_subdiv" }, { "rendering/quality/shadow_atlas/quadrant_2_subdiv", "rendering/lights_and_shadows/shadow_atlas/quadrant_2_subdiv" }, @@ -1400,7 +1399,6 @@ const char *RenamesMap3To4::project_godot_renames[][2] = { { "quality/shading/force_lambert_over_burley", "shading/overrides/force_lambert_over_burley" }, { "quality/shading/force_lambert_over_burley.mobile", "shading/overrides/force_lambert_over_burley.mobile" }, { "quality/shading/force_vertex_shading", "shading/overrides/force_vertex_shading" }, - { "quality/shading/force_vertex_shading.mobile", "shading/overrides/force_vertex_shading.mobile" }, { "quality/shadow_atlas/quadrant_0_subdiv", "lights_and_shadows/shadow_atlas/quadrant_0_subdiv" }, { "quality/shadow_atlas/quadrant_1_subdiv", "lights_and_shadows/shadow_atlas/quadrant_1_subdiv" }, { "quality/shadow_atlas/quadrant_2_subdiv", "lights_and_shadows/shadow_atlas/quadrant_2_subdiv" }, diff --git a/methods.py b/methods.py index 3f11d39bd0..411ce59d9e 100644 --- a/methods.py +++ b/methods.py @@ -795,9 +795,9 @@ def get_compiler_version(env): "major": -1, "minor": -1, "patch": -1, - "metadata1": None, - "metadata2": None, - "date": None, + "metadata1": "", + "metadata2": "", + "date": "", "apple_major": -1, "apple_minor": -1, "apple_patch1": -1, @@ -806,7 +806,20 @@ def get_compiler_version(env): } if env.msvc and not using_clang(env): - # TODO: Implement for MSVC + try: + args = [env["VSWHERE"], "-latest", "-products", "*", "-requires", "Microsoft.Component.MSBuild"] + version = subprocess.check_output(args, encoding="utf-8").strip() + for line in version.splitlines(): + split = line.split(":", 1) + if split[0] == "catalog_productDisplayVersion": + sem_ver = split[1].split(".") + ret["major"] = int(sem_ver[0]) + ret["minor"] = int(sem_ver[1]) + ret["patch"] = int(sem_ver[2]) + if split[0] == "catalog_buildVersion": + ret["metadata1"] = split[1] + except (subprocess.CalledProcessError, OSError): + print_warning("Couldn't find vswhere to determine compiler version.") return ret # Not using -dumpversion as some GCC distros only return major, and diff --git a/modules/bcdec/SCsub b/modules/bcdec/SCsub new file mode 100644 index 0000000000..32198eff96 --- /dev/null +++ b/modules/bcdec/SCsub @@ -0,0 +1,10 @@ +#!/usr/bin/env python +from misc.utility.scons_hints import * + +Import("env") +Import("env_modules") + +env_bcdec = env_modules.Clone() + +# Godot source files +env_bcdec.add_source_files(env.modules_sources, "*.cpp") diff --git a/modules/squish/config.py b/modules/bcdec/config.py index d22f9454ed..d22f9454ed 100644 --- a/modules/squish/config.py +++ b/modules/bcdec/config.py diff --git a/modules/bcdec/image_decompress_bcdec.cpp b/modules/bcdec/image_decompress_bcdec.cpp new file mode 100644 index 0000000000..30ca1fccb3 --- /dev/null +++ b/modules/bcdec/image_decompress_bcdec.cpp @@ -0,0 +1,181 @@ +/**************************************************************************/ +/* image_decompress_bcdec.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "image_decompress_bcdec.h" + +#include "core/os/os.h" +#include "core/string/print_string.h" + +#define BCDEC_IMPLEMENTATION +#include "thirdparty/misc/bcdec.h" + +inline void bcdec_bc6h_half_s(const void *compressedBlock, void *decompressedBlock, int destinationPitch) { + bcdec_bc6h_half(compressedBlock, decompressedBlock, destinationPitch, true); +} + +inline void bcdec_bc6h_half_u(const void *compressedBlock, void *decompressedBlock, int destinationPitch) { + bcdec_bc6h_half(compressedBlock, decompressedBlock, destinationPitch, false); +} + +static void decompress_image(BCdecFormat format, const void *src, void *dst, const uint64_t width, const uint64_t height) { + const uint8_t *src_blocks = reinterpret_cast<const uint8_t *>(src); + uint8_t *dec_blocks = reinterpret_cast<uint8_t *>(dst); + uint64_t src_pos = 0, dst_pos = 0; + +#define DECOMPRESS_LOOP(func, block_size, color_bytesize, color_components) \ + for (uint64_t y = 0; y < height; y += 4) { \ + for (uint64_t x = 0; x < width; x += 4) { \ + func(&src_blocks[src_pos], &dec_blocks[dst_pos], width *color_components); \ + src_pos += block_size; \ + dst_pos += 4 * color_bytesize; \ + } \ + dst_pos += 3 * width * color_bytesize; \ + } + + switch (format) { + case BCdec_BC1: { + DECOMPRESS_LOOP(bcdec_bc1, BCDEC_BC1_BLOCK_SIZE, 4, 4) + } break; + case BCdec_BC2: { + DECOMPRESS_LOOP(bcdec_bc2, BCDEC_BC2_BLOCK_SIZE, 4, 4) + } break; + case BCdec_BC3: { + DECOMPRESS_LOOP(bcdec_bc3, BCDEC_BC3_BLOCK_SIZE, 4, 4) + } break; + case BCdec_BC4: { + DECOMPRESS_LOOP(bcdec_bc4, BCDEC_BC4_BLOCK_SIZE, 1, 1) + } break; + case BCdec_BC5: { + DECOMPRESS_LOOP(bcdec_bc5, BCDEC_BC5_BLOCK_SIZE, 2, 2) + } break; + case BCdec_BC6U: { + DECOMPRESS_LOOP(bcdec_bc6h_half_u, BCDEC_BC6H_BLOCK_SIZE, 6, 3) + } break; + case BCdec_BC6S: { + DECOMPRESS_LOOP(bcdec_bc6h_half_s, BCDEC_BC6H_BLOCK_SIZE, 6, 3) + } break; + case BCdec_BC7: { + DECOMPRESS_LOOP(bcdec_bc7, BCDEC_BC7_BLOCK_SIZE, 4, 4) + } break; + } + +#undef DECOMPRESS_LOOP +} + +void image_decompress_bcdec(Image *p_image) { + uint64_t start_time = OS::get_singleton()->get_ticks_msec(); + + int w = p_image->get_width(); + int h = p_image->get_height(); + + Image::Format source_format = p_image->get_format(); + Image::Format target_format = Image::FORMAT_MAX; + + BCdecFormat bcdec_format = BCdec_BC1; + + switch (source_format) { + case Image::FORMAT_DXT1: + bcdec_format = BCdec_BC1; + target_format = Image::FORMAT_RGBA8; + break; + + case Image::FORMAT_DXT3: + bcdec_format = BCdec_BC2; + target_format = Image::FORMAT_RGBA8; + break; + + case Image::FORMAT_DXT5: + case Image::FORMAT_DXT5_RA_AS_RG: + bcdec_format = BCdec_BC3; + target_format = Image::FORMAT_RGBA8; + break; + + case Image::FORMAT_RGTC_R: + bcdec_format = BCdec_BC4; + target_format = Image::FORMAT_R8; + break; + + case Image::FORMAT_RGTC_RG: + bcdec_format = BCdec_BC5; + target_format = Image::FORMAT_RG8; + break; + + case Image::FORMAT_BPTC_RGBFU: + bcdec_format = BCdec_BC6U; + target_format = Image::FORMAT_RGBH; + break; + + case Image::FORMAT_BPTC_RGBF: + bcdec_format = BCdec_BC6S; + target_format = Image::FORMAT_RGBH; + break; + + case Image::FORMAT_BPTC_RGBA: + bcdec_format = BCdec_BC7; + target_format = Image::FORMAT_RGBA8; + break; + + default: + ERR_FAIL_MSG("bcdec: Can't decompress unknown format: " + Image::get_format_name(source_format) + "."); + break; + } + + int mm_count = p_image->get_mipmap_count(); + int64_t target_size = Image::get_image_data_size(w, h, target_format, p_image->has_mipmaps()); + + Vector<uint8_t> data; + data.resize(target_size); + + const uint8_t *rb = p_image->get_data().ptr(); + uint8_t *wb = data.ptrw(); + + // Decompress mipmaps. + for (int i = 0; i <= mm_count; i++) { + int64_t src_ofs = 0, mipmap_size = 0; + int mipmap_w = 0, mipmap_h = 0; + p_image->get_mipmap_offset_size_and_dimensions(i, src_ofs, mipmap_size, mipmap_w, mipmap_h); + + int64_t dst_ofs = Image::get_image_mipmap_offset(p_image->get_width(), p_image->get_height(), target_format, i); + decompress_image(bcdec_format, rb + src_ofs, wb + dst_ofs, mipmap_w, mipmap_h); + + w >>= 1; + h >>= 1; + } + + p_image->set_data(p_image->get_width(), p_image->get_height(), p_image->has_mipmaps(), target_format, data); + + // Swap channels if necessary. + if (source_format == Image::FORMAT_DXT5_RA_AS_RG) { + p_image->convert_ra_rgba8_to_rg(); + } + + print_verbose(vformat("bcdec: Decompression of a %dx%d %s image with %d mipmaps took %d ms.", + p_image->get_width(), p_image->get_height(), Image::get_format_name(source_format), p_image->get_mipmap_count(), OS::get_singleton()->get_ticks_msec() - start_time)); +} diff --git a/modules/squish/image_decompress_squish.h b/modules/bcdec/image_decompress_bcdec.h index 53c5d344a5..b82ceed9a4 100644 --- a/modules/squish/image_decompress_squish.h +++ b/modules/bcdec/image_decompress_bcdec.h @@ -1,5 +1,5 @@ /**************************************************************************/ -/* image_decompress_squish.h */ +/* image_decompress_bcdec.h */ /**************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,11 +28,22 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef IMAGE_DECOMPRESS_SQUISH_H -#define IMAGE_DECOMPRESS_SQUISH_H +#ifndef IMAGE_DECOMPRESS_BCDEC_H +#define IMAGE_DECOMPRESS_BCDEC_H #include "core/io/image.h" -void image_decompress_squish(Image *p_image); +enum BCdecFormat { + BCdec_BC1, + BCdec_BC2, + BCdec_BC3, + BCdec_BC4, + BCdec_BC5, + BCdec_BC6S, + BCdec_BC6U, + BCdec_BC7, +}; -#endif // IMAGE_DECOMPRESS_SQUISH_H +void image_decompress_bcdec(Image *p_image); + +#endif // IMAGE_DECOMPRESS_BCDEC_H diff --git a/modules/squish/register_types.cpp b/modules/bcdec/register_types.cpp index af7cf8f4f1..cbf9c0d383 100644 --- a/modules/squish/register_types.cpp +++ b/modules/bcdec/register_types.cpp @@ -30,17 +30,18 @@ #include "register_types.h" -#include "image_decompress_squish.h" +#include "image_decompress_bcdec.h" -void initialize_squish_module(ModuleInitializationLevel p_level) { +void initialize_bcdec_module(ModuleInitializationLevel p_level) { if (p_level != MODULE_INITIALIZATION_LEVEL_SCENE) { return; } - Image::_image_decompress_bc = image_decompress_squish; + Image::_image_decompress_bc = image_decompress_bcdec; + Image::_image_decompress_bptc = image_decompress_bcdec; } -void uninitialize_squish_module(ModuleInitializationLevel p_level) { +void uninitialize_bcdec_module(ModuleInitializationLevel p_level) { if (p_level != MODULE_INITIALIZATION_LEVEL_SCENE) { return; } diff --git a/modules/squish/register_types.h b/modules/bcdec/register_types.h index 1786b28ed3..eb721e3f2a 100644 --- a/modules/squish/register_types.h +++ b/modules/bcdec/register_types.h @@ -28,12 +28,12 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef SQUISH_REGISTER_TYPES_H -#define SQUISH_REGISTER_TYPES_H +#ifndef BCDEC_REGISTER_TYPES_H +#define BCDEC_REGISTER_TYPES_H #include "modules/register_module_types.h" -void initialize_squish_module(ModuleInitializationLevel p_level); -void uninitialize_squish_module(ModuleInitializationLevel p_level); +void initialize_bcdec_module(ModuleInitializationLevel p_level); +void uninitialize_bcdec_module(ModuleInitializationLevel p_level); -#endif // SQUISH_REGISTER_TYPES_H +#endif // BCDEC_REGISTER_TYPES_H diff --git a/modules/cvtt/register_types.cpp b/modules/cvtt/register_types.cpp index 211d419349..80e3062d04 100644 --- a/modules/cvtt/register_types.cpp +++ b/modules/cvtt/register_types.cpp @@ -40,7 +40,6 @@ void initialize_cvtt_module(ModuleInitializationLevel p_level) { } Image::set_compress_bptc_func(image_compress_cvtt); - Image::_image_decompress_bptc = image_decompress_cvtt; } void uninitialize_cvtt_module(ModuleInitializationLevel p_level) { diff --git a/modules/gdscript/doc_classes/@GDScript.xml b/modules/gdscript/doc_classes/@GDScript.xml index f539f27848..5fe47d69df 100644 --- a/modules/gdscript/doc_classes/@GDScript.xml +++ b/modules/gdscript/doc_classes/@GDScript.xml @@ -669,6 +669,41 @@ [b]Note:[/b] Subgroups cannot be nested, they only provide one extra level of depth. Just like the next group ends the previous group, so do the subsequent subgroups. </description> </annotation> + <annotation name="@export_tool_button"> + <return type="void" /> + <param index="0" name="text" type="String" /> + <param index="1" name="icon" type="String" default="""" /> + <description> + Export a [Callable] property as a clickable button with the label [param text]. When the button is pressed, the callable is called. + If [param icon] is specified, it is used to fetch an icon for the button via [method Control.get_theme_icon], from the [code]"EditorIcons"[/code] theme type. If [param icon] is omitted, the default [code]"Callable"[/code] icon is used instead. + Consider using the [EditorUndoRedoManager] to allow the action to be reverted safely. + See also [constant PROPERTY_HINT_TOOL_BUTTON]. + [codeblock] + @tool + extends Sprite2D + + @export_tool_button("Hello") var hello_action = hello + @export_tool_button("Randomize the color!", "ColorRect") + var randomize_color_action = randomize_color + + func hello(): + print("Hello world!") + + func randomize_color(): + var undo_redo = EditorInterface.get_editor_undo_redo() + undo_redo.create_action("Randomized Sprite2D Color") + undo_redo.add_do_property(self, &"self_modulate", Color(randf(), randf(), randf())) + undo_redo.add_undo_property(self, &"self_modulate", self_modulate) + undo_redo.commit_action() + [/codeblock] + [b]Note:[/b] The property is exported without the [constant PROPERTY_USAGE_STORAGE] flag because a [Callable] cannot be properly serialized and stored in a file. + [b]Note:[/b] In an exported project neither [EditorInterface] nor [EditorUndoRedoManager] exist, which may cause some scripts to break. To prevent this, you can use [method Engine.get_singleton] and omit the static type from the variable declaration: + [codeblock] + var undo_redo = Engine.get_singleton(&"EditorInterface").get_editor_undo_redo() + [/codeblock] + [b]Note:[/b] Avoid storing lambda callables in member variables of [RefCounted]-based classes (e.g. resources), as this can lead to memory leaks. Use only method callables and optionally [method Callable.bind] or [method Callable.unbind]. + </description> + </annotation> <annotation name="@icon"> <return type="void" /> <param index="0" name="icon_path" type="String" /> diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp index 65aa150be3..e169566705 100644 --- a/modules/gdscript/gdscript_parser.cpp +++ b/modules/gdscript/gdscript_parser.cpp @@ -122,6 +122,7 @@ GDScriptParser::GDScriptParser() { register_annotation(MethodInfo("@export_flags_avoidance"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_LAYERS_AVOIDANCE, Variant::INT>); register_annotation(MethodInfo("@export_storage"), AnnotationInfo::VARIABLE, &GDScriptParser::export_storage_annotation); register_annotation(MethodInfo("@export_custom", PropertyInfo(Variant::INT, "hint", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_CLASS_IS_ENUM, "PropertyHint"), PropertyInfo(Variant::STRING, "hint_string"), PropertyInfo(Variant::INT, "usage", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_CLASS_IS_BITFIELD, "PropertyUsageFlags")), AnnotationInfo::VARIABLE, &GDScriptParser::export_custom_annotation, varray(PROPERTY_USAGE_DEFAULT)); + register_annotation(MethodInfo("@export_tool_button", PropertyInfo(Variant::STRING, "text"), PropertyInfo(Variant::STRING, "icon")), AnnotationInfo::VARIABLE, &GDScriptParser::export_tool_button_annotation, varray("")); // Export grouping annotations. register_annotation(MethodInfo("@export_category", PropertyInfo(Variant::STRING, "name")), AnnotationInfo::STANDALONE, &GDScriptParser::export_group_annotations<PROPERTY_USAGE_CATEGORY>); register_annotation(MethodInfo("@export_group", PropertyInfo(Variant::STRING, "name"), PropertyInfo(Variant::STRING, "prefix")), AnnotationInfo::STANDALONE, &GDScriptParser::export_group_annotations<PROPERTY_USAGE_GROUP>, varray("")); @@ -4618,10 +4619,10 @@ bool GDScriptParser::export_annotations(AnnotationNode *p_annotation, Node *p_ta // For `@export_storage` and `@export_custom`, there is no need to check the variable type, argument values, // or handle array exports in a special way, so they are implemented as separate methods. -bool GDScriptParser::export_storage_annotation(AnnotationNode *p_annotation, Node *p_node, ClassNode *p_class) { - ERR_FAIL_COND_V_MSG(p_node->type != Node::VARIABLE, false, vformat(R"("%s" annotation can only be applied to variables.)", p_annotation->name)); +bool GDScriptParser::export_storage_annotation(AnnotationNode *p_annotation, Node *p_target, ClassNode *p_class) { + ERR_FAIL_COND_V_MSG(p_target->type != Node::VARIABLE, false, vformat(R"("%s" annotation can only be applied to variables.)", p_annotation->name)); - VariableNode *variable = static_cast<VariableNode *>(p_node); + VariableNode *variable = static_cast<VariableNode *>(p_target); if (variable->is_static) { push_error(vformat(R"(Annotation "%s" cannot be applied to a static variable.)", p_annotation->name), p_annotation); return false; @@ -4640,11 +4641,11 @@ bool GDScriptParser::export_storage_annotation(AnnotationNode *p_annotation, Nod return true; } -bool GDScriptParser::export_custom_annotation(AnnotationNode *p_annotation, Node *p_node, ClassNode *p_class) { - ERR_FAIL_COND_V_MSG(p_node->type != Node::VARIABLE, false, vformat(R"("%s" annotation can only be applied to variables.)", p_annotation->name)); +bool GDScriptParser::export_custom_annotation(AnnotationNode *p_annotation, Node *p_target, ClassNode *p_class) { + ERR_FAIL_COND_V_MSG(p_target->type != Node::VARIABLE, false, vformat(R"("%s" annotation can only be applied to variables.)", p_annotation->name)); ERR_FAIL_COND_V_MSG(p_annotation->resolved_arguments.size() < 2, false, R"(Annotation "@export_custom" requires 2 arguments.)"); - VariableNode *variable = static_cast<VariableNode *>(p_node); + VariableNode *variable = static_cast<VariableNode *>(p_target); if (variable->is_static) { push_error(vformat(R"(Annotation "%s" cannot be applied to a static variable.)", p_annotation->name), p_annotation); return false; @@ -4668,12 +4669,56 @@ bool GDScriptParser::export_custom_annotation(AnnotationNode *p_annotation, Node return true; } -template <PropertyUsageFlags t_usage> -bool GDScriptParser::export_group_annotations(AnnotationNode *p_annotation, Node *p_target, ClassNode *p_class) { - if (p_annotation->resolved_arguments.is_empty()) { +bool GDScriptParser::export_tool_button_annotation(AnnotationNode *p_annotation, Node *p_target, ClassNode *p_class) { +#ifdef TOOLS_ENABLED + ERR_FAIL_COND_V_MSG(p_target->type != Node::VARIABLE, false, vformat(R"("%s" annotation can only be applied to variables.)", p_annotation->name)); + ERR_FAIL_COND_V(p_annotation->resolved_arguments.is_empty(), false); + + if (!is_tool()) { + push_error(R"(Tool buttons can only be used in tool scripts (add "@tool" to the top of the script).)", p_annotation); + return false; + } + + VariableNode *variable = static_cast<VariableNode *>(p_target); + + if (variable->is_static) { + push_error(vformat(R"(Annotation "%s" cannot be applied to a static variable.)", p_annotation->name), p_annotation); + return false; + } + if (variable->exported) { + push_error(vformat(R"(Annotation "%s" cannot be used with another "@export" annotation.)", p_annotation->name), p_annotation); return false; } + const DataType variable_type = variable->get_datatype(); + if (!variable_type.is_variant() && variable_type.is_hard_type()) { + if (variable_type.kind != DataType::BUILTIN || variable_type.builtin_type != Variant::CALLABLE) { + push_error(vformat(R"("@export_tool_button" annotation requires a variable of type "Callable", but type "%s" was given instead.)", variable_type.to_string()), p_annotation); + return false; + } + } + + variable->exported = true; + + // Build the hint string (format: `<text>[,<icon>]`). + String hint_string = p_annotation->resolved_arguments[0].operator String(); // Button text. + if (p_annotation->resolved_arguments.size() > 1) { + hint_string += "," + p_annotation->resolved_arguments[1].operator String(); // Button icon. + } + + variable->export_info.type = Variant::CALLABLE; + variable->export_info.hint = PROPERTY_HINT_TOOL_BUTTON; + variable->export_info.hint_string = hint_string; + variable->export_info.usage = PROPERTY_USAGE_EDITOR; +#endif // TOOLS_ENABLED + + return true; // Only available in editor. +} + +template <PropertyUsageFlags t_usage> +bool GDScriptParser::export_group_annotations(AnnotationNode *p_annotation, Node *p_target, ClassNode *p_class) { + ERR_FAIL_COND_V(p_annotation->resolved_arguments.is_empty(), false); + p_annotation->export_info.name = p_annotation->resolved_arguments[0]; switch (t_usage) { diff --git a/modules/gdscript/gdscript_parser.h b/modules/gdscript/gdscript_parser.h index 7840474a89..7f64ae902b 100644 --- a/modules/gdscript/gdscript_parser.h +++ b/modules/gdscript/gdscript_parser.h @@ -1507,6 +1507,7 @@ private: bool export_annotations(AnnotationNode *p_annotation, Node *p_target, ClassNode *p_class); bool export_storage_annotation(AnnotationNode *p_annotation, Node *p_target, ClassNode *p_class); bool export_custom_annotation(AnnotationNode *p_annotation, Node *p_target, ClassNode *p_class); + bool export_tool_button_annotation(AnnotationNode *p_annotation, Node *p_target, ClassNode *p_class); template <PropertyUsageFlags t_usage> bool export_group_annotations(AnnotationNode *p_annotation, Node *p_target, ClassNode *p_class); bool warning_annotations(AnnotationNode *p_annotation, Node *p_target, ClassNode *p_class); diff --git a/modules/gdscript/tests/scripts/parser/errors/export_tool_button_requires_tool_mode.gd b/modules/gdscript/tests/scripts/parser/errors/export_tool_button_requires_tool_mode.gd new file mode 100644 index 0000000000..48be5b2541 --- /dev/null +++ b/modules/gdscript/tests/scripts/parser/errors/export_tool_button_requires_tool_mode.gd @@ -0,0 +1 @@ +@export_tool_button("Click me!") var action diff --git a/modules/gdscript/tests/scripts/parser/errors/export_tool_button_requires_tool_mode.out b/modules/gdscript/tests/scripts/parser/errors/export_tool_button_requires_tool_mode.out new file mode 100644 index 0000000000..fb148308e4 --- /dev/null +++ b/modules/gdscript/tests/scripts/parser/errors/export_tool_button_requires_tool_mode.out @@ -0,0 +1,2 @@ +GDTEST_ANALYZER_ERROR +Tool buttons can only be used in tool scripts (add "@tool" to the top of the script). diff --git a/modules/gdscript/tests/scripts/parser/features/export_variable.gd b/modules/gdscript/tests/scripts/parser/features/export_variable.gd index 1e134d0e0e..8aa449f602 100644 --- a/modules/gdscript/tests/scripts/parser/features/export_variable.gd +++ b/modules/gdscript/tests/scripts/parser/features/export_variable.gd @@ -1,3 +1,4 @@ +@tool class_name ExportVariableTest extends Node @@ -47,6 +48,10 @@ const PreloadedUnnamedClass = preload("./export_variable_unnamed.notest.gd") @export_custom(PROPERTY_HINT_ENUM, "A,B,C") var test_export_custom_weak_int = 5 @export_custom(PROPERTY_HINT_ENUM, "A,B,C") var test_export_custom_hard_int: int = 6 +# `@export_tool_button`. +@export_tool_button("Click me!") var test_tool_button_1: Callable +@export_tool_button("Click me!", "ColorRect") var test_tool_button_2: Callable + func test(): for property in get_property_list(): if str(property.name).begins_with("test_"): diff --git a/modules/gdscript/tests/scripts/parser/features/export_variable.out b/modules/gdscript/tests/scripts/parser/features/export_variable.out index d10462bb8d..0d915e00e6 100644 --- a/modules/gdscript/tests/scripts/parser/features/export_variable.out +++ b/modules/gdscript/tests/scripts/parser/features/export_variable.out @@ -55,3 +55,7 @@ var test_export_custom_weak_int: int = 5 hint=ENUM hint_string="A,B,C" usage=DEFAULT|SCRIPT_VARIABLE class_name=&"" var test_export_custom_hard_int: int = 6 hint=ENUM hint_string="A,B,C" usage=DEFAULT|SCRIPT_VARIABLE class_name=&"" +var test_tool_button_1: Callable = Callable() + hint=TOOL_BUTTON hint_string="Click me!" usage=EDITOR|SCRIPT_VARIABLE class_name=&"" +var test_tool_button_2: Callable = Callable() + hint=TOOL_BUTTON hint_string="Click me!,ColorRect" usage=EDITOR|SCRIPT_VARIABLE class_name=&"" diff --git a/modules/gdscript/tests/scripts/utils.notest.gd b/modules/gdscript/tests/scripts/utils.notest.gd index 1e2788f765..fa289e442f 100644 --- a/modules/gdscript/tests/scripts/utils.notest.gd +++ b/modules/gdscript/tests/scripts/utils.notest.gd @@ -205,6 +205,9 @@ static func get_property_hint_name(hint: PropertyHint) -> String: return "PROPERTY_HINT_HIDE_QUATERNION_EDIT" PROPERTY_HINT_PASSWORD: return "PROPERTY_HINT_PASSWORD" + PROPERTY_HINT_TOOL_BUTTON: + return "PROPERTY_HINT_TOOL_BUTTON" + printerr("Argument `hint` is invalid. Use `PROPERTY_HINT_*` constants.") return "<invalid hint>" diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/EventSignals_ScriptSignals.generated.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/EventSignals_ScriptSignals.generated.cs index cc45e5746f..188972e6fe 100644 --- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/EventSignals_ScriptSignals.generated.cs +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/EventSignals_ScriptSignals.generated.cs @@ -32,6 +32,10 @@ partial class EventSignals add => backing_MySignal += value; remove => backing_MySignal -= value; } + protected void OnMySignal(string str, int num) + { + EmitSignal(SignalName.MySignal, str, num); + } /// <inheritdoc/> [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] protected override void RaiseGodotClassSignalCallbacks(in godot_string_name signal, NativeVariantPtrArgs args) diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ExtensionMethods.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ExtensionMethods.cs index 957d5789df..62fa7b0a36 100644 --- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ExtensionMethods.cs +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ExtensionMethods.cs @@ -155,6 +155,32 @@ namespace Godot.SourceGenerators }; } + public static string GetAccessibilityKeyword(this INamedTypeSymbol namedTypeSymbol) + { + if (namedTypeSymbol.DeclaredAccessibility == Accessibility.NotApplicable) + { + // Accessibility not specified. Get the default accessibility. + return namedTypeSymbol.ContainingSymbol switch + { + null or INamespaceSymbol => "internal", + ITypeSymbol { TypeKind: TypeKind.Class or TypeKind.Struct } => "private", + ITypeSymbol { TypeKind: TypeKind.Interface } => "public", + _ => "", + }; + } + + return namedTypeSymbol.DeclaredAccessibility switch + { + Accessibility.Private => "private", + Accessibility.Protected => "protected", + Accessibility.Internal => "internal", + Accessibility.ProtectedAndInternal => "private", + Accessibility.ProtectedOrInternal => "private", + Accessibility.Public => "public", + _ => "", + }; + } + public static string NameWithTypeParameters(this INamedTypeSymbol symbol) { return symbol.IsGenericType ? diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSignalsGenerator.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSignalsGenerator.cs index 54f2212339..0dda43ab4c 100644 --- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSignalsGenerator.cs +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSignalsGenerator.cs @@ -5,13 +5,6 @@ using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Text; -// TODO: -// Determine a proper way to emit the signal. -// 'Emit(nameof(TheEvent))' creates a StringName every time and has the overhead of string marshaling. -// I haven't decided on the best option yet. Some possibilities: -// - Expose the generated StringName fields to the user, for use with 'Emit(...)'. -// - Generate a 'EmitSignalName' method for each event signal. - namespace Godot.SourceGenerators { [Generator] @@ -276,7 +269,7 @@ namespace Godot.SourceGenerators source.Append( $" /// <inheritdoc cref=\"{signalDelegate.DelegateSymbol.FullQualifiedNameIncludeGlobal()}\"/>\n"); - source.Append(" public event ") + source.Append($" {signalDelegate.DelegateSymbol.GetAccessibilityKeyword()} event ") .Append(signalDelegate.DelegateSymbol.FullQualifiedNameIncludeGlobal()) .Append(" @") .Append(signalName) @@ -288,6 +281,43 @@ namespace Godot.SourceGenerators .Append(signalName) .Append(" -= value;\n") .Append("}\n"); + + // Generate On{EventName} method to raise the event + + var invokeMethodSymbol = signalDelegate.InvokeMethodData.Method; + int paramCount = invokeMethodSymbol.Parameters.Length; + + string raiseMethodModifiers = signalDelegate.DelegateSymbol.ContainingType.IsSealed ? + "private" : + "protected"; + + source.Append($" {raiseMethodModifiers} void On{signalName}("); + for (int i = 0; i < paramCount; i++) + { + var paramSymbol = invokeMethodSymbol.Parameters[i]; + source.Append($"{paramSymbol.Type.FullQualifiedNameIncludeGlobal()} {paramSymbol.Name}"); + if (i < paramCount - 1) + { + source.Append(", "); + } + } + source.Append(")\n"); + source.Append(" {\n"); + source.Append($" EmitSignal(SignalName.{signalName}"); + foreach (var paramSymbol in invokeMethodSymbol.Parameters) + { + // Enums must be converted to the underlying type before they can be implicitly converted to Variant + if (paramSymbol.Type.TypeKind == TypeKind.Enum) + { + var underlyingType = ((INamedTypeSymbol)paramSymbol.Type).EnumUnderlyingType; + source.Append($", ({underlyingType.FullQualifiedNameIncludeGlobal()}){paramSymbol.Name}"); + continue; + } + + source.Append($", {paramSymbol.Name}"); + } + source.Append(");\n"); + source.Append(" }\n"); } // Generate RaiseGodotClassSignalCallbacks diff --git a/modules/mono/editor/bindings_generator.cpp b/modules/mono/editor/bindings_generator.cpp index a467aae2e9..89655e0b56 100644 --- a/modules/mono/editor/bindings_generator.cpp +++ b/modules/mono/editor/bindings_generator.cpp @@ -3227,6 +3227,46 @@ Error BindingsGenerator::_generate_cs_signal(const BindingsGenerator::TypeInterf } p_output.append(CLOSE_BLOCK_L1); + + // Generate On{EventName} method to raise the event. + if (!p_itype.is_singleton) { + p_output.append(MEMBER_BEGIN "protected void "); + p_output << "On" << p_isignal.proxy_name; + if (is_parameterless) { + p_output.append("()\n" OPEN_BLOCK_L1 INDENT2); + p_output << "EmitSignal(SignalName." << p_isignal.proxy_name << ");\n"; + p_output.append(CLOSE_BLOCK_L1); + } else { + p_output.append("("); + + StringBuilder cs_emitsignal_params; + + int idx = 0; + for (const ArgumentInterface &iarg : p_isignal.arguments) { + const TypeInterface *arg_type = _get_type_or_null(iarg.type); + ERR_FAIL_NULL_V_MSG(arg_type, ERR_BUG, "Argument type '" + iarg.type.cname + "' was not found."); + + if (idx != 0) { + p_output << ", "; + cs_emitsignal_params << ", "; + } + + p_output << arg_type->cs_type << " " << iarg.name; + + if (arg_type->is_enum) { + cs_emitsignal_params << "(long)"; + } + + cs_emitsignal_params << iarg.name; + + idx++; + } + + p_output.append(")\n" OPEN_BLOCK_L1 INDENT2); + p_output << "EmitSignal(SignalName." << p_isignal.proxy_name << ", " << cs_emitsignal_params << ");\n"; + p_output.append(CLOSE_BLOCK_L1); + } + } } return OK; diff --git a/modules/squish/SCsub b/modules/squish/SCsub deleted file mode 100644 index d8e7fbc142..0000000000 --- a/modules/squish/SCsub +++ /dev/null @@ -1,45 +0,0 @@ -#!/usr/bin/env python -from misc.utility.scons_hints import * - -Import("env") -Import("env_modules") - -env_squish = env_modules.Clone() - -# Thirdparty source files - -thirdparty_obj = [] - -if env["builtin_squish"]: - thirdparty_dir = "#thirdparty/squish/" - thirdparty_sources = [ - "alpha.cpp", - "clusterfit.cpp", - "colourblock.cpp", - "colourfit.cpp", - "colourset.cpp", - "maths.cpp", - "rangefit.cpp", - "singlecolourfit.cpp", - "squish.cpp", - ] - - thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] - - env_squish.Prepend(CPPPATH=[thirdparty_dir]) - - env_thirdparty = env_squish.Clone() - env_thirdparty.disable_warnings() - env_thirdparty.add_source_files(thirdparty_obj, thirdparty_sources) - env.modules_sources += thirdparty_obj - - -# Godot source files - -module_obj = [] - -env_squish.add_source_files(module_obj, "*.cpp") -env.modules_sources += module_obj - -# Needed to force rebuilding the module files when the thirdparty library is updated. -env.Depends(module_obj, thirdparty_obj) diff --git a/platform/android/doc_classes/EditorExportPlatformAndroid.xml b/platform/android/doc_classes/EditorExportPlatformAndroid.xml index 020e432155..2fe5539e56 100644 --- a/platform/android/doc_classes/EditorExportPlatformAndroid.xml +++ b/platform/android/doc_classes/EditorExportPlatformAndroid.xml @@ -102,6 +102,9 @@ <member name="launcher_icons/adaptive_foreground_432x432" type="String" setter="" getter=""> Foreground layer of the application adaptive icon file. See [url=https://developer.android.com/develop/ui/views/launch/icon_design_adaptive#design-adaptive-icons]Design adaptive icons[/url]. </member> + <member name="launcher_icons/adaptive_monochrome_432x432" type="String" setter="" getter=""> + Monochrome layer of the application adaptive icon file. See [url=https://developer.android.com/develop/ui/views/launch/icon_design_adaptive#design-adaptive-icons]Design adaptive icons[/url]. + </member> <member name="launcher_icons/main_192x192" type="String" setter="" getter=""> Application icon file. If left empty, it will fallback to [member ProjectSettings.application/config/icon]. </member> diff --git a/platform/android/export/export_plugin.cpp b/platform/android/export/export_plugin.cpp index e3d9807af7..cfd258cddc 100644 --- a/platform/android/export/export_plugin.cpp +++ b/platform/android/export/export_plugin.cpp @@ -222,6 +222,7 @@ static const int icon_densities_count = 6; static const char *launcher_icon_option = PNAME("launcher_icons/main_192x192"); static const char *launcher_adaptive_icon_foreground_option = PNAME("launcher_icons/adaptive_foreground_432x432"); static const char *launcher_adaptive_icon_background_option = PNAME("launcher_icons/adaptive_background_432x432"); +static const char *launcher_adaptive_icon_monochrome_option = PNAME("launcher_icons/adaptive_monochrome_432x432"); static const LauncherIcon launcher_icons[icon_densities_count] = { { "res/mipmap-xxxhdpi-v4/icon.png", 192 }, @@ -250,6 +251,15 @@ static const LauncherIcon launcher_adaptive_icon_backgrounds[icon_densities_coun { "res/mipmap/icon_background.png", 432 } }; +static const LauncherIcon launcher_adaptive_icon_monochromes[icon_densities_count] = { + { "res/mipmap-xxxhdpi-v4/icon_monochrome.png", 432 }, + { "res/mipmap-xxhdpi-v4/icon_monochrome.png", 324 }, + { "res/mipmap-xhdpi-v4/icon_monochrome.png", 216 }, + { "res/mipmap-hdpi-v4/icon_monochrome.png", 162 }, + { "res/mipmap-mdpi-v4/icon_monochrome.png", 108 }, + { "res/mipmap/icon_monochrome.png", 432 } +}; + static const int EXPORT_FORMAT_APK = 0; static const int EXPORT_FORMAT_AAB = 1; @@ -1644,12 +1654,13 @@ void EditorExportPlatformAndroid::_process_launcher_icons(const String &p_file_n } } -void EditorExportPlatformAndroid::load_icon_refs(const Ref<EditorExportPreset> &p_preset, Ref<Image> &icon, Ref<Image> &foreground, Ref<Image> &background) { +void EditorExportPlatformAndroid::load_icon_refs(const Ref<EditorExportPreset> &p_preset, Ref<Image> &icon, Ref<Image> &foreground, Ref<Image> &background, Ref<Image> &monochrome) { String project_icon_path = GLOBAL_GET("application/config/icon"); icon.instantiate(); foreground.instantiate(); background.instantiate(); + monochrome.instantiate(); // Regular icon: user selection -> project icon -> default. String path = static_cast<String>(p_preset->get(launcher_icon_option)).strip_edges(); @@ -1677,12 +1688,20 @@ void EditorExportPlatformAndroid::load_icon_refs(const Ref<EditorExportPreset> & print_verbose("Loading adaptive background icon from " + path); ImageLoader::load_image(path, background); } + + // Adaptive monochrome: user selection -> default. + path = static_cast<String>(p_preset->get(launcher_adaptive_icon_monochrome_option)).strip_edges(); + if (!path.is_empty()) { + print_verbose("Loading adaptive monochrome icon from " + path); + ImageLoader::load_image(path, background); + } } void EditorExportPlatformAndroid::_copy_icons_to_gradle_project(const Ref<EditorExportPreset> &p_preset, const Ref<Image> &p_main_image, const Ref<Image> &p_foreground, - const Ref<Image> &p_background) { + const Ref<Image> &p_background, + const Ref<Image> &p_monochrome) { String gradle_build_dir = ExportTemplateManager::get_android_build_directory(p_preset); // Prepare images to be resized for the icons. If some image ends up being uninitialized, @@ -1711,6 +1730,14 @@ void EditorExportPlatformAndroid::_copy_icons_to_gradle_project(const Ref<Editor launcher_adaptive_icon_backgrounds[i].dimensions, data); store_file_at_path(gradle_build_dir.path_join(launcher_adaptive_icon_backgrounds[i].export_path), data); } + + if (p_monochrome.is_valid() && !p_monochrome->is_empty()) { + print_verbose("Processing launcher adaptive icon p_monochrome for dimension " + itos(launcher_adaptive_icon_monochromes[i].dimensions) + " into " + launcher_adaptive_icon_monochromes[i].export_path); + Vector<uint8_t> data; + _process_launcher_icons(launcher_adaptive_icon_monochromes[i].export_path, p_monochrome, + launcher_adaptive_icon_monochromes[i].dimensions, data); + store_file_at_path(gradle_build_dir.path_join(launcher_adaptive_icon_monochromes[i].export_path), data); + } } } @@ -1875,6 +1902,7 @@ void EditorExportPlatformAndroid::get_export_options(List<ExportOption> *r_optio r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, launcher_icon_option, PROPERTY_HINT_FILE, "*.png"), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, launcher_adaptive_icon_foreground_option, PROPERTY_HINT_FILE, "*.png"), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, launcher_adaptive_icon_background_option, PROPERTY_HINT_FILE, "*.png"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, launcher_adaptive_icon_monochrome_option, PROPERTY_HINT_FILE, "*.png"), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "graphics/opengl_debug"), false)); @@ -3035,8 +3063,9 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP Ref<Image> main_image; Ref<Image> foreground; Ref<Image> background; + Ref<Image> monochrome; - load_icon_refs(p_preset, main_image, foreground, background); + load_icon_refs(p_preset, main_image, foreground, background, monochrome); Vector<uint8_t> command_line_flags; // Write command line flags into the command_line_flags variable. @@ -3107,7 +3136,7 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), TTR("Unable to overwrite res/*.xml files with project name.")); } // Copies the project icon files into the appropriate Gradle project directory. - _copy_icons_to_gradle_project(p_preset, main_image, foreground, background); + _copy_icons_to_gradle_project(p_preset, main_image, foreground, background, monochrome); // Write an AndroidManifest.xml file into the Gradle project directory. _write_tmp_manifest(p_preset, p_give_internet, p_debug); @@ -3446,6 +3475,11 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP _process_launcher_icons(file, background, launcher_adaptive_icon_backgrounds[i].dimensions, data); } } + if (monochrome.is_valid() && !monochrome->is_empty()) { + if (file == launcher_adaptive_icon_monochromes[i].export_path) { + _process_launcher_icons(file, monochrome, launcher_adaptive_icon_monochromes[i].dimensions, data); + } + } } } diff --git a/platform/android/export/export_plugin.h b/platform/android/export/export_plugin.h index 708288fbf4..7e1d626486 100644 --- a/platform/android/export/export_plugin.h +++ b/platform/android/export/export_plugin.h @@ -167,12 +167,13 @@ class EditorExportPlatformAndroid : public EditorExportPlatform { void _process_launcher_icons(const String &p_file_name, const Ref<Image> &p_source_image, int dimension, Vector<uint8_t> &p_data); - void load_icon_refs(const Ref<EditorExportPreset> &p_preset, Ref<Image> &icon, Ref<Image> &foreground, Ref<Image> &background); + void load_icon_refs(const Ref<EditorExportPreset> &p_preset, Ref<Image> &icon, Ref<Image> &foreground, Ref<Image> &background, Ref<Image> &monochrome); void _copy_icons_to_gradle_project(const Ref<EditorExportPreset> &p_preset, const Ref<Image> &p_main_image, const Ref<Image> &p_foreground, - const Ref<Image> &p_background); + const Ref<Image> &p_background, + const Ref<Image> &p_monochrome); static void _create_editor_debug_keystore_if_needed(); diff --git a/platform/android/java/editor/src/horizonos/java/org/godotengine/editor/GodotEditor.kt b/platform/android/java/editor/src/horizonos/java/org/godotengine/editor/GodotEditor.kt index 6cb08ae94b..9dc34f2267 100644 --- a/platform/android/java/editor/src/horizonos/java/org/godotengine/editor/GodotEditor.kt +++ b/platform/android/java/editor/src/horizonos/java/org/godotengine/editor/GodotEditor.kt @@ -45,14 +45,14 @@ open class GodotEditor : BaseGodotEditor() { internal val XR_RUN_GAME_INFO = EditorWindowInfo(GodotXRGame::class.java, 1667, ":GodotXRGame") - internal const val USE_SCENE_PERMISSION = "com.oculus.permission.USE_SCENE" + internal val USE_SCENE_PERMISSIONS = listOf("com.oculus.permission.USE_SCENE", "horizonos.permission.USE_SCENE") } override fun getExcludedPermissions(): MutableSet<String> { val excludedPermissions = super.getExcludedPermissions() // The USE_SCENE permission is requested when the "xr/openxr/enabled" project setting // is enabled. - excludedPermissions.add(USE_SCENE_PERMISSION) + excludedPermissions.addAll(USE_SCENE_PERMISSIONS) return excludedPermissions } diff --git a/platform/android/java/editor/src/horizonos/java/org/godotengine/editor/GodotXRGame.kt b/platform/android/java/editor/src/horizonos/java/org/godotengine/editor/GodotXRGame.kt index 5db2879aad..0c82791e89 100644 --- a/platform/android/java/editor/src/horizonos/java/org/godotengine/editor/GodotXRGame.kt +++ b/platform/android/java/editor/src/horizonos/java/org/godotengine/editor/GodotXRGame.kt @@ -69,7 +69,7 @@ open class GodotXRGame: GodotGame() { val automaticPermissionsRequestEnabled = automaticallyRequestPermissionsSetting.isNullOrEmpty() || automaticallyRequestPermissionsSetting.toBoolean() if (automaticPermissionsRequestEnabled) { - permissionsToEnable.add(USE_SCENE_PERMISSION) + permissionsToEnable.addAll(USE_SCENE_PERMISSIONS) } } diff --git a/platform/android/java/lib/res/mipmap-anydpi-v26/icon.xml b/platform/android/java/lib/res/mipmap-anydpi-v26/icon.xml index cfdcca2ab5..bb2ae6bee5 100644 --- a/platform/android/java/lib/res/mipmap-anydpi-v26/icon.xml +++ b/platform/android/java/lib/res/mipmap-anydpi-v26/icon.xml @@ -2,4 +2,5 @@ <adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android"> <background android:drawable="@mipmap/icon_background"/> <foreground android:drawable="@mipmap/icon_foreground"/> + <monochrome android:drawable="@mipmap/icon_monochrome"/> </adaptive-icon> diff --git a/platform/android/java/lib/res/mipmap/icon_monochrome.png b/platform/android/java/lib/res/mipmap/icon_monochrome.png Binary files differnew file mode 100644 index 0000000000..28f59ea119 --- /dev/null +++ b/platform/android/java/lib/res/mipmap/icon_monochrome.png diff --git a/platform/linuxbsd/detect.py b/platform/linuxbsd/detect.py index d1de760f34..a67434527c 100644 --- a/platform/linuxbsd/detect.py +++ b/platform/linuxbsd/detect.py @@ -256,10 +256,6 @@ def configure(env: "SConsEnvironment"): if not env["builtin_enet"]: env.ParseConfig("pkg-config libenet --cflags --libs") - if not env["builtin_squish"]: - # libsquish doesn't reliably install its .pc file, so some distros lack it. - env.Append(LIBS=["libsquish"]) - if not env["builtin_zstd"]: env.ParseConfig("pkg-config libzstd --cflags --libs") diff --git a/scene/3d/mesh_instance_3d.cpp b/scene/3d/mesh_instance_3d.cpp index f551cb401c..e8166802f8 100644 --- a/scene/3d/mesh_instance_3d.cpp +++ b/scene/3d/mesh_instance_3d.cpp @@ -332,8 +332,8 @@ void MeshInstance3D::create_multiple_convex_collisions(const Ref<MeshConvexDecom void MeshInstance3D::_notification(int p_what) { switch (p_what) { - case NOTIFICATION_ENTER_TREE: { - _resolve_skeleton_path(); + case NOTIFICATION_READY: { + callable_mp(this, &MeshInstance3D::_resolve_skeleton_path).call_deferred(); } break; case NOTIFICATION_TRANSLATION_CHANGED: { if (mesh.is_valid()) { diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp index 11a6411e65..cf8815679f 100644 --- a/scene/gui/graph_edit.cpp +++ b/scene/gui/graph_edit.cpp @@ -1999,6 +1999,9 @@ void GraphEdit::gui_input(const Ref<InputEvent> &p_ev) { } else if (p_ev->is_action("ui_copy", true)) { emit_signal(SNAME("copy_nodes_request")); accept_event(); + } else if (p_ev->is_action("ui_cut", true)) { + emit_signal(SNAME("cut_nodes_request")); + accept_event(); } else if (p_ev->is_action("ui_paste", true)) { emit_signal(SNAME("paste_nodes_request")); accept_event(); @@ -2735,6 +2738,7 @@ void GraphEdit::_bind_methods() { ADD_SIGNAL(MethodInfo("connection_drag_ended")); ADD_SIGNAL(MethodInfo("copy_nodes_request")); + ADD_SIGNAL(MethodInfo("cut_nodes_request")); ADD_SIGNAL(MethodInfo("paste_nodes_request")); ADD_SIGNAL(MethodInfo("duplicate_nodes_request")); ADD_SIGNAL(MethodInfo("delete_nodes_request", PropertyInfo(Variant::ARRAY, "nodes", PROPERTY_HINT_ARRAY_TYPE, "StringName"))); diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp index 927e76e4b2..ab25aabb81 100644 --- a/scene/resources/material.cpp +++ b/scene/resources/material.cpp @@ -113,12 +113,12 @@ void Material::inspect_native_shader_code() { RID Material::get_shader_rid() const { RID ret; - GDVIRTUAL_REQUIRED_CALL(_get_shader_rid, ret); + GDVIRTUAL_CALL(_get_shader_rid, ret); return ret; } Shader::Mode Material::get_shader_mode() const { Shader::Mode ret = Shader::MODE_MAX; - GDVIRTUAL_REQUIRED_CALL(_get_shader_mode, ret); + GDVIRTUAL_CALL(_get_shader_mode, ret); return ret; } diff --git a/scene/resources/material.h b/scene/resources/material.h index 50a774e961..25c4450682 100644 --- a/scene/resources/material.h +++ b/scene/resources/material.h @@ -66,8 +66,8 @@ protected: void _mark_initialized(const Callable &p_add_to_dirty_list, const Callable &p_update_shader); bool _is_initialized() { return init_state == INIT_STATE_READY; } - GDVIRTUAL0RC(RID, _get_shader_rid) - GDVIRTUAL0RC(Shader::Mode, _get_shader_mode) + GDVIRTUAL0RC_REQUIRED(RID, _get_shader_rid) + GDVIRTUAL0RC_REQUIRED(Shader::Mode, _get_shader_mode) GDVIRTUAL0RC(bool, _can_do_next_pass) GDVIRTUAL0RC(bool, _can_use_render_priority) public: diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp index 22e2e9138f..4d1d733f8b 100644 --- a/scene/resources/mesh.cpp +++ b/scene/resources/mesh.cpp @@ -205,81 +205,81 @@ Mesh::ConvexDecompositionFunc Mesh::convex_decomposition_function = nullptr; int Mesh::get_surface_count() const { int ret = 0; - GDVIRTUAL_REQUIRED_CALL(_get_surface_count, ret); + GDVIRTUAL_CALL(_get_surface_count, ret); return ret; } int Mesh::surface_get_array_len(int p_idx) const { int ret = 0; - GDVIRTUAL_REQUIRED_CALL(_surface_get_array_len, p_idx, ret); + GDVIRTUAL_CALL(_surface_get_array_len, p_idx, ret); return ret; } int Mesh::surface_get_array_index_len(int p_idx) const { int ret = 0; - GDVIRTUAL_REQUIRED_CALL(_surface_get_array_index_len, p_idx, ret); + GDVIRTUAL_CALL(_surface_get_array_index_len, p_idx, ret); return ret; } Array Mesh::surface_get_arrays(int p_surface) const { Array ret; - GDVIRTUAL_REQUIRED_CALL(_surface_get_arrays, p_surface, ret); + GDVIRTUAL_CALL(_surface_get_arrays, p_surface, ret); return ret; } TypedArray<Array> Mesh::surface_get_blend_shape_arrays(int p_surface) const { TypedArray<Array> ret; - GDVIRTUAL_REQUIRED_CALL(_surface_get_blend_shape_arrays, p_surface, ret); + GDVIRTUAL_CALL(_surface_get_blend_shape_arrays, p_surface, ret); return ret; } Dictionary Mesh::surface_get_lods(int p_surface) const { Dictionary ret; - GDVIRTUAL_REQUIRED_CALL(_surface_get_lods, p_surface, ret); + GDVIRTUAL_CALL(_surface_get_lods, p_surface, ret); return ret; } BitField<Mesh::ArrayFormat> Mesh::surface_get_format(int p_idx) const { uint32_t ret = 0; - GDVIRTUAL_REQUIRED_CALL(_surface_get_format, p_idx, ret); + GDVIRTUAL_CALL(_surface_get_format, p_idx, ret); return ret; } Mesh::PrimitiveType Mesh::surface_get_primitive_type(int p_idx) const { uint32_t ret = PRIMITIVE_MAX; - GDVIRTUAL_REQUIRED_CALL(_surface_get_primitive_type, p_idx, ret); + GDVIRTUAL_CALL(_surface_get_primitive_type, p_idx, ret); return (Mesh::PrimitiveType)ret; } void Mesh::surface_set_material(int p_idx, const Ref<Material> &p_material) { - GDVIRTUAL_REQUIRED_CALL(_surface_set_material, p_idx, p_material); + GDVIRTUAL_CALL(_surface_set_material, p_idx, p_material); } Ref<Material> Mesh::surface_get_material(int p_idx) const { Ref<Material> ret; - GDVIRTUAL_REQUIRED_CALL(_surface_get_material, p_idx, ret); + GDVIRTUAL_CALL(_surface_get_material, p_idx, ret); return ret; } int Mesh::get_blend_shape_count() const { int ret = 0; - GDVIRTUAL_REQUIRED_CALL(_get_blend_shape_count, ret); + GDVIRTUAL_CALL(_get_blend_shape_count, ret); return ret; } StringName Mesh::get_blend_shape_name(int p_index) const { StringName ret; - GDVIRTUAL_REQUIRED_CALL(_get_blend_shape_name, p_index, ret); + GDVIRTUAL_CALL(_get_blend_shape_name, p_index, ret); return ret; } void Mesh::set_blend_shape_name(int p_index, const StringName &p_name) { - GDVIRTUAL_REQUIRED_CALL(_set_blend_shape_name, p_index, p_name); + GDVIRTUAL_CALL(_set_blend_shape_name, p_index, p_name); } AABB Mesh::get_aabb() const { AABB ret; - GDVIRTUAL_REQUIRED_CALL(_get_aabb, ret); + GDVIRTUAL_CALL(_get_aabb, ret); return ret; } diff --git a/scene/resources/mesh.h b/scene/resources/mesh.h index 13fd986e81..068bfb6708 100644 --- a/scene/resources/mesh.h +++ b/scene/resources/mesh.h @@ -68,20 +68,20 @@ public: protected: static void _bind_methods(); - GDVIRTUAL0RC(int, _get_surface_count) - GDVIRTUAL1RC(int, _surface_get_array_len, int) - GDVIRTUAL1RC(int, _surface_get_array_index_len, int) - GDVIRTUAL1RC(Array, _surface_get_arrays, int) - GDVIRTUAL1RC(TypedArray<Array>, _surface_get_blend_shape_arrays, int) - GDVIRTUAL1RC(Dictionary, _surface_get_lods, int) - GDVIRTUAL1RC(uint32_t, _surface_get_format, int) - GDVIRTUAL1RC(uint32_t, _surface_get_primitive_type, int) - GDVIRTUAL2(_surface_set_material, int, Ref<Material>) - GDVIRTUAL1RC(Ref<Material>, _surface_get_material, int) - GDVIRTUAL0RC(int, _get_blend_shape_count) - GDVIRTUAL1RC(StringName, _get_blend_shape_name, int) - GDVIRTUAL2(_set_blend_shape_name, int, StringName) - GDVIRTUAL0RC(AABB, _get_aabb) + GDVIRTUAL0RC_REQUIRED(int, _get_surface_count) + GDVIRTUAL1RC_REQUIRED(int, _surface_get_array_len, int) + GDVIRTUAL1RC_REQUIRED(int, _surface_get_array_index_len, int) + GDVIRTUAL1RC_REQUIRED(Array, _surface_get_arrays, int) + GDVIRTUAL1RC_REQUIRED(TypedArray<Array>, _surface_get_blend_shape_arrays, int) + GDVIRTUAL1RC_REQUIRED(Dictionary, _surface_get_lods, int) + GDVIRTUAL1RC_REQUIRED(uint32_t, _surface_get_format, int) + GDVIRTUAL1RC_REQUIRED(uint32_t, _surface_get_primitive_type, int) + GDVIRTUAL2_REQUIRED(_surface_set_material, int, Ref<Material>) + GDVIRTUAL1RC_REQUIRED(Ref<Material>, _surface_get_material, int) + GDVIRTUAL0RC_REQUIRED(int, _get_blend_shape_count) + GDVIRTUAL1RC_REQUIRED(StringName, _get_blend_shape_name, int) + GDVIRTUAL2_REQUIRED(_set_blend_shape_name, int, StringName) + GDVIRTUAL0RC_REQUIRED(AABB, _get_aabb) public: enum { diff --git a/scene/resources/style_box.cpp b/scene/resources/style_box.cpp index f87bf1ee05..1203c21a1b 100644 --- a/scene/resources/style_box.cpp +++ b/scene/resources/style_box.cpp @@ -90,7 +90,7 @@ Point2 StyleBox::get_offset() const { } void StyleBox::draw(RID p_canvas_item, const Rect2 &p_rect) const { - GDVIRTUAL_REQUIRED_CALL(_draw, p_canvas_item, p_rect); + GDVIRTUAL_CALL(_draw, p_canvas_item, p_rect); } Rect2 StyleBox::get_draw_rect(const Rect2 &p_rect) const { diff --git a/scene/resources/style_box.h b/scene/resources/style_box.h index 3d3a059d0b..e09b271c47 100644 --- a/scene/resources/style_box.h +++ b/scene/resources/style_box.h @@ -48,7 +48,7 @@ protected: static void _bind_methods(); virtual float get_style_margin(Side p_side) const { return 0; } - GDVIRTUAL2C(_draw, RID, Rect2) + GDVIRTUAL2C_REQUIRED(_draw, RID, Rect2) GDVIRTUAL1RC(Rect2, _get_draw_rect, Rect2) GDVIRTUAL0RC(Size2, _get_minimum_size) GDVIRTUAL2RC(bool, _test_mask, Point2, Rect2) diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp index 0efaad61fe..7713181a4b 100644 --- a/scene/resources/texture.cpp +++ b/scene/resources/texture.cpp @@ -34,13 +34,13 @@ int Texture2D::get_width() const { int ret = 0; - GDVIRTUAL_REQUIRED_CALL(_get_width, ret); + GDVIRTUAL_CALL(_get_width, ret); return ret; } int Texture2D::get_height() const { int ret = 0; - GDVIRTUAL_REQUIRED_CALL(_get_height, ret); + GDVIRTUAL_CALL(_get_height, ret); return ret; } @@ -133,37 +133,37 @@ TypedArray<Image> Texture3D::_get_datai() const { Image::Format Texture3D::get_format() const { Image::Format ret = Image::FORMAT_MAX; - GDVIRTUAL_REQUIRED_CALL(_get_format, ret); + GDVIRTUAL_CALL(_get_format, ret); return ret; } int Texture3D::get_width() const { int ret = 0; - GDVIRTUAL_REQUIRED_CALL(_get_width, ret); + GDVIRTUAL_CALL(_get_width, ret); return ret; } int Texture3D::get_height() const { int ret = 0; - GDVIRTUAL_REQUIRED_CALL(_get_height, ret); + GDVIRTUAL_CALL(_get_height, ret); return ret; } int Texture3D::get_depth() const { int ret = 0; - GDVIRTUAL_REQUIRED_CALL(_get_depth, ret); + GDVIRTUAL_CALL(_get_depth, ret); return ret; } bool Texture3D::has_mipmaps() const { bool ret = false; - GDVIRTUAL_REQUIRED_CALL(_has_mipmaps, ret); + GDVIRTUAL_CALL(_has_mipmaps, ret); return ret; } Vector<Ref<Image>> Texture3D::get_data() const { TypedArray<Image> ret; - GDVIRTUAL_REQUIRED_CALL(_get_data, ret); + GDVIRTUAL_CALL(_get_data, ret); Vector<Ref<Image>> data; data.resize(ret.size()); for (int i = 0; i < data.size(); i++) { @@ -198,43 +198,43 @@ Ref<Resource> Texture3D::create_placeholder() const { Image::Format TextureLayered::get_format() const { Image::Format ret = Image::FORMAT_MAX; - GDVIRTUAL_REQUIRED_CALL(_get_format, ret); + GDVIRTUAL_CALL(_get_format, ret); return ret; } TextureLayered::LayeredType TextureLayered::get_layered_type() const { uint32_t ret = LAYERED_TYPE_2D_ARRAY; - GDVIRTUAL_REQUIRED_CALL(_get_layered_type, ret); + GDVIRTUAL_CALL(_get_layered_type, ret); return (LayeredType)ret; } int TextureLayered::get_width() const { int ret = 0; - GDVIRTUAL_REQUIRED_CALL(_get_width, ret); + GDVIRTUAL_CALL(_get_width, ret); return ret; } int TextureLayered::get_height() const { int ret = 0; - GDVIRTUAL_REQUIRED_CALL(_get_height, ret); + GDVIRTUAL_CALL(_get_height, ret); return ret; } int TextureLayered::get_layers() const { int ret = 0; - GDVIRTUAL_REQUIRED_CALL(_get_layers, ret); + GDVIRTUAL_CALL(_get_layers, ret); return ret; } bool TextureLayered::has_mipmaps() const { bool ret = false; - GDVIRTUAL_REQUIRED_CALL(_has_mipmaps, ret); + GDVIRTUAL_CALL(_has_mipmaps, ret); return ret; } Ref<Image> TextureLayered::get_layer_data(int p_layer) const { Ref<Image> ret; - GDVIRTUAL_REQUIRED_CALL(_get_layer_data, p_layer, ret); + GDVIRTUAL_CALL(_get_layer_data, p_layer, ret); return ret; } diff --git a/scene/resources/texture.h b/scene/resources/texture.h index e7840804bf..cdad884e71 100644 --- a/scene/resources/texture.h +++ b/scene/resources/texture.h @@ -57,8 +57,8 @@ class Texture2D : public Texture { protected: static void _bind_methods(); - GDVIRTUAL0RC(int, _get_width) - GDVIRTUAL0RC(int, _get_height) + GDVIRTUAL0RC_REQUIRED(int, _get_width) + GDVIRTUAL0RC_REQUIRED(int, _get_height) GDVIRTUAL2RC(bool, _is_pixel_opaque, int, int) GDVIRTUAL0RC(bool, _has_alpha) @@ -93,13 +93,13 @@ class TextureLayered : public Texture { protected: static void _bind_methods(); - GDVIRTUAL0RC(Image::Format, _get_format) - GDVIRTUAL0RC(uint32_t, _get_layered_type) - GDVIRTUAL0RC(int, _get_width) - GDVIRTUAL0RC(int, _get_height) - GDVIRTUAL0RC(int, _get_layers) - GDVIRTUAL0RC(bool, _has_mipmaps) - GDVIRTUAL1RC(Ref<Image>, _get_layer_data, int) + GDVIRTUAL0RC_REQUIRED(Image::Format, _get_format) + GDVIRTUAL0RC_REQUIRED(uint32_t, _get_layered_type) + GDVIRTUAL0RC_REQUIRED(int, _get_width) + GDVIRTUAL0RC_REQUIRED(int, _get_height) + GDVIRTUAL0RC_REQUIRED(int, _get_layers) + GDVIRTUAL0RC_REQUIRED(bool, _has_mipmaps) + GDVIRTUAL1RC_REQUIRED(Ref<Image>, _get_layer_data, int) public: enum LayeredType { LAYERED_TYPE_2D_ARRAY, @@ -128,12 +128,12 @@ protected: TypedArray<Image> _get_datai() const; - GDVIRTUAL0RC(Image::Format, _get_format) - GDVIRTUAL0RC(int, _get_width) - GDVIRTUAL0RC(int, _get_height) - GDVIRTUAL0RC(int, _get_depth) - GDVIRTUAL0RC(bool, _has_mipmaps) - GDVIRTUAL0RC(TypedArray<Image>, _get_data) + GDVIRTUAL0RC_REQUIRED(Image::Format, _get_format) + GDVIRTUAL0RC_REQUIRED(int, _get_width) + GDVIRTUAL0RC_REQUIRED(int, _get_height) + GDVIRTUAL0RC_REQUIRED(int, _get_depth) + GDVIRTUAL0RC_REQUIRED(bool, _has_mipmaps) + GDVIRTUAL0RC_REQUIRED(TypedArray<Image>, _get_data) public: virtual Image::Format get_format() const; virtual int get_width() const; diff --git a/scene/resources/video_stream.cpp b/scene/resources/video_stream.cpp index 3d31fe0491..1fcc1821dc 100644 --- a/scene/resources/video_stream.cpp +++ b/scene/resources/video_stream.cpp @@ -119,7 +119,7 @@ Ref<Texture2D> VideoStreamPlayback::get_texture() const { } void VideoStreamPlayback::update(double p_delta) { - GDVIRTUAL_REQUIRED_CALL(_update, p_delta); + GDVIRTUAL_CALL(_update, p_delta); } void VideoStreamPlayback::set_mix_callback(AudioMixCallback p_callback, void *p_userdata) { diff --git a/scene/resources/video_stream.h b/scene/resources/video_stream.h index dc54f4b769..3843cc99c4 100644 --- a/scene/resources/video_stream.h +++ b/scene/resources/video_stream.h @@ -56,7 +56,7 @@ protected: GDVIRTUAL1(_seek, double); GDVIRTUAL1(_set_audio_track, int); GDVIRTUAL0RC(Ref<Texture2D>, _get_texture); - GDVIRTUAL1(_update, double); + GDVIRTUAL1_REQUIRED(_update, double); GDVIRTUAL0RC(int, _get_channels); GDVIRTUAL0RC(int, _get_mix_rate); diff --git a/scene/scene_string_names.cpp b/scene/scene_string_names.cpp index f8a0336b37..140e588291 100644 --- a/scene/scene_string_names.cpp +++ b/scene/scene_string_names.cpp @@ -141,5 +141,6 @@ SceneStringNames::SceneStringNames() { confirmed = StaticCString::create("confirmed"); text_changed = StaticCString::create("text_changed"); + text_submitted = StaticCString::create("text_submitted"); value_changed = StaticCString::create("value_changed"); } diff --git a/scene/scene_string_names.h b/scene/scene_string_names.h index 381a161ad5..fc22be33b2 100644 --- a/scene/scene_string_names.h +++ b/scene/scene_string_names.h @@ -154,6 +154,7 @@ public: StringName confirmed; StringName text_changed; + StringName text_submitted; StringName value_changed; }; diff --git a/servers/audio/audio_effect.cpp b/servers/audio/audio_effect.cpp index 28a957cf6f..ac334eb764 100644 --- a/servers/audio/audio_effect.cpp +++ b/servers/audio/audio_effect.cpp @@ -31,7 +31,7 @@ #include "audio_effect.h" void AudioEffectInstance::process(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count) { - GDVIRTUAL_REQUIRED_CALL(_process, p_src_frames, p_dst_frames, p_frame_count); + GDVIRTUAL_CALL(_process, p_src_frames, p_dst_frames, p_frame_count); } bool AudioEffectInstance::process_silence() const { bool ret = false; @@ -48,7 +48,7 @@ void AudioEffectInstance::_bind_methods() { Ref<AudioEffectInstance> AudioEffect::instantiate() { Ref<AudioEffectInstance> ret; - GDVIRTUAL_REQUIRED_CALL(_instantiate, ret); + GDVIRTUAL_CALL(_instantiate, ret); return ret; } void AudioEffect::_bind_methods() { diff --git a/servers/audio/audio_effect.h b/servers/audio/audio_effect.h index 9952246c20..cef5bfec5e 100644 --- a/servers/audio/audio_effect.h +++ b/servers/audio/audio_effect.h @@ -40,7 +40,7 @@ class AudioEffectInstance : public RefCounted { GDCLASS(AudioEffectInstance, RefCounted); protected: - GDVIRTUAL3(_process, GDExtensionConstPtr<AudioFrame>, GDExtensionPtr<AudioFrame>, int) + GDVIRTUAL3_REQUIRED(_process, GDExtensionConstPtr<AudioFrame>, GDExtensionPtr<AudioFrame>, int) GDVIRTUAL0RC(bool, _process_silence) static void _bind_methods(); @@ -53,7 +53,7 @@ class AudioEffect : public Resource { GDCLASS(AudioEffect, Resource); protected: - GDVIRTUAL0R(Ref<AudioEffectInstance>, _instantiate) + GDVIRTUAL0R_REQUIRED(Ref<AudioEffectInstance>, _instantiate) static void _bind_methods(); public: diff --git a/servers/audio/audio_stream.cpp b/servers/audio/audio_stream.cpp index ece088a694..1886ebe1ac 100644 --- a/servers/audio/audio_stream.cpp +++ b/servers/audio/audio_stream.cpp @@ -72,7 +72,7 @@ void AudioStreamPlayback::seek(double p_time) { int AudioStreamPlayback::mix(AudioFrame *p_buffer, float p_rate_scale, int p_frames) { int ret = 0; - GDVIRTUAL_REQUIRED_CALL(_mix, p_buffer, p_rate_scale, p_frames, ret); + GDVIRTUAL_CALL(_mix, p_buffer, p_rate_scale, p_frames, ret); return ret; } @@ -132,12 +132,12 @@ void AudioStreamPlaybackResampled::begin_resample() { int AudioStreamPlaybackResampled::_mix_internal(AudioFrame *p_buffer, int p_frames) { int ret = 0; - GDVIRTUAL_REQUIRED_CALL(_mix_resampled, p_buffer, p_frames, ret); + GDVIRTUAL_CALL(_mix_resampled, p_buffer, p_frames, ret); return ret; } float AudioStreamPlaybackResampled::get_stream_sampling_rate() { float ret = 0; - GDVIRTUAL_REQUIRED_CALL(_get_stream_sampling_rate, ret); + GDVIRTUAL_CALL(_get_stream_sampling_rate, ret); return ret; } diff --git a/servers/audio/audio_stream.h b/servers/audio/audio_stream.h index 7f2b68a796..3feaa53630 100644 --- a/servers/audio/audio_stream.h +++ b/servers/audio/audio_stream.h @@ -89,7 +89,7 @@ protected: GDVIRTUAL0RC(int, _get_loop_count) GDVIRTUAL0RC(double, _get_playback_position) GDVIRTUAL1(_seek, double) - GDVIRTUAL3R(int, _mix, GDExtensionPtr<AudioFrame>, float, int) + GDVIRTUAL3R_REQUIRED(int, _mix, GDExtensionPtr<AudioFrame>, float, int) GDVIRTUAL0(_tag_used_streams) GDVIRTUAL2(_set_parameter, const StringName &, const Variant &) GDVIRTUAL1RC(Variant, _get_parameter, const StringName &) @@ -141,8 +141,8 @@ protected: virtual int _mix_internal(AudioFrame *p_buffer, int p_frames); virtual float get_stream_sampling_rate(); - GDVIRTUAL2R(int, _mix_resampled, GDExtensionPtr<AudioFrame>, int) - GDVIRTUAL0RC(float, _get_stream_sampling_rate) + GDVIRTUAL2R_REQUIRED(int, _mix_resampled, GDExtensionPtr<AudioFrame>, int) + GDVIRTUAL0RC_REQUIRED(float, _get_stream_sampling_rate) static void _bind_methods(); diff --git a/servers/extensions/physics_server_2d_extension.h b/servers/extensions/physics_server_2d_extension.h index 6e0277a7c6..7bbd84ddf4 100644 --- a/servers/extensions/physics_server_2d_extension.h +++ b/servers/extensions/physics_server_2d_extension.h @@ -127,53 +127,53 @@ protected: static void _bind_methods(); bool is_body_excluded_from_query(const RID &p_body) const; - GDVIRTUAL7R(bool, _intersect_ray, const Vector2 &, const Vector2 &, uint32_t, bool, bool, bool, GDExtensionPtr<PhysicsServer2DExtensionRayResult>) - GDVIRTUAL7R(int, _intersect_point, const Vector2 &, ObjectID, uint32_t, bool, bool, GDExtensionPtr<PhysicsServer2DExtensionShapeResult>, int) - GDVIRTUAL9R(int, _intersect_shape, RID, const Transform2D &, const Vector2 &, real_t, uint32_t, bool, bool, GDExtensionPtr<PhysicsServer2DExtensionShapeResult>, int) - GDVIRTUAL9R(bool, _cast_motion, RID, const Transform2D &, const Vector2 &, real_t, uint32_t, bool, bool, GDExtensionPtr<real_t>, GDExtensionPtr<real_t>) - GDVIRTUAL10R(bool, _collide_shape, RID, const Transform2D &, const Vector2 &, real_t, uint32_t, bool, bool, GDExtensionPtr<Vector2>, int, GDExtensionPtr<int>) - GDVIRTUAL8R(bool, _rest_info, RID, const Transform2D &, const Vector2 &, real_t, uint32_t, bool, bool, GDExtensionPtr<PhysicsServer2DExtensionShapeRestInfo>) + GDVIRTUAL7R_REQUIRED(bool, _intersect_ray, const Vector2 &, const Vector2 &, uint32_t, bool, bool, bool, GDExtensionPtr<PhysicsServer2DExtensionRayResult>) + GDVIRTUAL7R_REQUIRED(int, _intersect_point, const Vector2 &, ObjectID, uint32_t, bool, bool, GDExtensionPtr<PhysicsServer2DExtensionShapeResult>, int) + GDVIRTUAL9R_REQUIRED(int, _intersect_shape, RID, const Transform2D &, const Vector2 &, real_t, uint32_t, bool, bool, GDExtensionPtr<PhysicsServer2DExtensionShapeResult>, int) + GDVIRTUAL9R_REQUIRED(bool, _cast_motion, RID, const Transform2D &, const Vector2 &, real_t, uint32_t, bool, bool, GDExtensionPtr<real_t>, GDExtensionPtr<real_t>) + GDVIRTUAL10R_REQUIRED(bool, _collide_shape, RID, const Transform2D &, const Vector2 &, real_t, uint32_t, bool, bool, GDExtensionPtr<Vector2>, int, GDExtensionPtr<int>) + GDVIRTUAL8R_REQUIRED(bool, _rest_info, RID, const Transform2D &, const Vector2 &, real_t, uint32_t, bool, bool, GDExtensionPtr<PhysicsServer2DExtensionShapeRestInfo>) public: virtual bool intersect_ray(const RayParameters &p_parameters, RayResult &r_result) override { exclude = &p_parameters.exclude; bool ret = false; - GDVIRTUAL_REQUIRED_CALL(_intersect_ray, p_parameters.from, p_parameters.to, p_parameters.collision_mask, p_parameters.collide_with_bodies, p_parameters.collide_with_areas, p_parameters.hit_from_inside, &r_result, ret); + GDVIRTUAL_CALL(_intersect_ray, p_parameters.from, p_parameters.to, p_parameters.collision_mask, p_parameters.collide_with_bodies, p_parameters.collide_with_areas, p_parameters.hit_from_inside, &r_result, ret); exclude = nullptr; return ret; } virtual int intersect_point(const PointParameters &p_parameters, ShapeResult *r_results, int p_result_max) override { exclude = &p_parameters.exclude; int ret = false; - GDVIRTUAL_REQUIRED_CALL(_intersect_point, p_parameters.position, p_parameters.canvas_instance_id, p_parameters.collision_mask, p_parameters.collide_with_bodies, p_parameters.collide_with_areas, r_results, p_result_max, ret); + GDVIRTUAL_CALL(_intersect_point, p_parameters.position, p_parameters.canvas_instance_id, p_parameters.collision_mask, p_parameters.collide_with_bodies, p_parameters.collide_with_areas, r_results, p_result_max, ret); exclude = nullptr; return ret; } virtual int intersect_shape(const ShapeParameters &p_parameters, ShapeResult *r_results, int p_result_max) override { exclude = &p_parameters.exclude; int ret = 0; - GDVIRTUAL_REQUIRED_CALL(_intersect_shape, p_parameters.shape_rid, p_parameters.transform, p_parameters.motion, p_parameters.margin, p_parameters.collision_mask, p_parameters.collide_with_bodies, p_parameters.collide_with_areas, r_results, p_result_max, ret); + GDVIRTUAL_CALL(_intersect_shape, p_parameters.shape_rid, p_parameters.transform, p_parameters.motion, p_parameters.margin, p_parameters.collision_mask, p_parameters.collide_with_bodies, p_parameters.collide_with_areas, r_results, p_result_max, ret); exclude = nullptr; return ret; } virtual bool cast_motion(const ShapeParameters &p_parameters, real_t &p_closest_safe, real_t &p_closest_unsafe) override { exclude = &p_parameters.exclude; bool ret = false; - GDVIRTUAL_REQUIRED_CALL(_cast_motion, p_parameters.shape_rid, p_parameters.transform, p_parameters.motion, p_parameters.margin, p_parameters.collision_mask, p_parameters.collide_with_bodies, p_parameters.collide_with_areas, &p_closest_safe, &p_closest_unsafe, ret); + GDVIRTUAL_CALL(_cast_motion, p_parameters.shape_rid, p_parameters.transform, p_parameters.motion, p_parameters.margin, p_parameters.collision_mask, p_parameters.collide_with_bodies, p_parameters.collide_with_areas, &p_closest_safe, &p_closest_unsafe, ret); exclude = nullptr; return ret; } virtual bool collide_shape(const ShapeParameters &p_parameters, Vector2 *r_results, int p_result_max, int &r_result_count) override { exclude = &p_parameters.exclude; bool ret = false; - GDVIRTUAL_REQUIRED_CALL(_collide_shape, p_parameters.shape_rid, p_parameters.transform, p_parameters.motion, p_parameters.margin, p_parameters.collision_mask, p_parameters.collide_with_bodies, p_parameters.collide_with_areas, r_results, p_result_max, &r_result_count, ret); + GDVIRTUAL_CALL(_collide_shape, p_parameters.shape_rid, p_parameters.transform, p_parameters.motion, p_parameters.margin, p_parameters.collision_mask, p_parameters.collide_with_bodies, p_parameters.collide_with_areas, r_results, p_result_max, &r_result_count, ret); exclude = nullptr; return ret; } virtual bool rest_info(const ShapeParameters &p_parameters, ShapeRestInfo *r_info) override { exclude = &p_parameters.exclude; bool ret = false; - GDVIRTUAL_REQUIRED_CALL(_rest_info, p_parameters.shape_rid, p_parameters.transform, p_parameters.motion, p_parameters.margin, p_parameters.collision_mask, p_parameters.collide_with_bodies, p_parameters.collide_with_areas, r_info, ret); + GDVIRTUAL_CALL(_rest_info, p_parameters.shape_rid, p_parameters.transform, p_parameters.motion, p_parameters.margin, p_parameters.collision_mask, p_parameters.collide_with_bodies, p_parameters.collide_with_areas, r_info, ret); exclude = nullptr; return ret; } @@ -191,9 +191,9 @@ class PhysicsServer2DExtension : public PhysicsServer2D { protected: static void _bind_methods(); - GDVIRTUAL9R(bool, _shape_collide, RID, const Transform2D &, const Vector2 &, RID, const Transform2D &, const Vector2 &, GDExtensionPtr<Vector2>, int, GDExtensionPtr<int>) + GDVIRTUAL9R_REQUIRED(bool, _shape_collide, RID, const Transform2D &, const Vector2 &, RID, const Transform2D &, const Vector2 &, GDExtensionPtr<Vector2>, int, GDExtensionPtr<int>) - GDVIRTUAL8R(bool, _body_collide_shape, RID, int, RID, const Transform2D &, const Vector2 &, GDExtensionPtr<Vector2>, int, GDExtensionPtr<int>) + GDVIRTUAL8R_REQUIRED(bool, _body_collide_shape, RID, int, RID, const Transform2D &, const Vector2 &, GDExtensionPtr<Vector2>, int, GDExtensionPtr<int>) public: // The warning is valid, but unavoidable. If the function is not overridden it will error anyway. @@ -218,7 +218,7 @@ public: virtual bool shape_collide(RID p_shape_A, const Transform2D &p_xform_A, const Vector2 &p_motion_A, RID p_shape_B, const Transform2D &p_xform_B, const Vector2 &p_motion_B, Vector2 *r_results, int p_result_max, int &r_result_count) override { bool ret = false; - GDVIRTUAL_REQUIRED_CALL(_shape_collide, p_shape_A, p_xform_A, p_motion_A, p_shape_B, p_xform_B, p_motion_B, r_results, p_result_max, &r_result_count, ret); + GDVIRTUAL_CALL(_shape_collide, p_shape_A, p_xform_A, p_motion_A, p_shape_B, p_xform_B, p_motion_B, r_results, p_result_max, &r_result_count, ret); return ret; } @@ -354,11 +354,11 @@ public: EXBIND2(body_add_collision_exception, RID, RID) EXBIND2(body_remove_collision_exception, RID, RID) - GDVIRTUAL1RC(TypedArray<RID>, _body_get_collision_exceptions, RID) + GDVIRTUAL1RC_REQUIRED(TypedArray<RID>, _body_get_collision_exceptions, RID) void body_get_collision_exceptions(RID p_body, List<RID> *p_exceptions) override { TypedArray<RID> ret; - GDVIRTUAL_REQUIRED_CALL(_body_get_collision_exceptions, p_body, ret); + GDVIRTUAL_CALL(_body_get_collision_exceptions, p_body, ret); for (int i = 0; i < ret.size(); i++) { p_exceptions->push_back(ret[i]); } @@ -378,7 +378,7 @@ public: virtual bool body_collide_shape(RID p_body, int p_body_shape, RID p_shape, const Transform2D &p_shape_xform, const Vector2 &p_motion, Vector2 *r_results, int p_result_max, int &r_result_count) override { bool ret = false; - GDVIRTUAL_REQUIRED_CALL(_body_collide_shape, p_body, p_body_shape, p_shape, p_shape_xform, p_motion, r_results, p_result_max, &r_result_count, ret); + GDVIRTUAL_CALL(_body_collide_shape, p_body, p_body_shape, p_shape, p_shape_xform, p_motion, r_results, p_result_max, &r_result_count, ret); return ret; } @@ -386,7 +386,7 @@ public: EXBIND1R(PhysicsDirectBodyState2D *, body_get_direct_state, RID) - GDVIRTUAL7RC(bool, _body_test_motion, RID, const Transform2D &, const Vector2 &, real_t, bool, bool, GDExtensionPtr<PhysicsServer2DExtensionMotionResult>) + GDVIRTUAL7RC_REQUIRED(bool, _body_test_motion, RID, const Transform2D &, const Vector2 &, real_t, bool, bool, GDExtensionPtr<PhysicsServer2DExtensionMotionResult>) thread_local static const HashSet<RID> *exclude_bodies; thread_local static const HashSet<ObjectID> *exclude_objects; @@ -398,7 +398,7 @@ public: bool ret = false; exclude_bodies = &p_parameters.exclude_bodies; exclude_objects = &p_parameters.exclude_objects; - GDVIRTUAL_REQUIRED_CALL(_body_test_motion, p_body, p_parameters.from, p_parameters.motion, p_parameters.margin, p_parameters.collide_separation_ray, p_parameters.recovery_as_collision, r_result, ret); + GDVIRTUAL_CALL(_body_test_motion, p_body, p_parameters.from, p_parameters.motion, p_parameters.margin, p_parameters.collide_separation_ray, p_parameters.recovery_as_collision, r_result, ret); exclude_bodies = nullptr; exclude_objects = nullptr; return ret; @@ -432,9 +432,9 @@ public: /* MISC */ - GDVIRTUAL1(_free_rid, RID) + GDVIRTUAL1_REQUIRED(_free_rid, RID) virtual void free(RID p_rid) override { - GDVIRTUAL_REQUIRED_CALL(_free_rid, p_rid); + GDVIRTUAL_CALL(_free_rid, p_rid); } EXBIND1(set_active, bool) diff --git a/servers/extensions/physics_server_3d_extension.h b/servers/extensions/physics_server_3d_extension.h index eb8b627245..b808b80b93 100644 --- a/servers/extensions/physics_server_3d_extension.h +++ b/servers/extensions/physics_server_3d_extension.h @@ -129,61 +129,61 @@ protected: static void _bind_methods(); bool is_body_excluded_from_query(const RID &p_body) const; - GDVIRTUAL9R(bool, _intersect_ray, const Vector3 &, const Vector3 &, uint32_t, bool, bool, bool, bool, bool, GDExtensionPtr<PhysicsServer3DExtensionRayResult>) - GDVIRTUAL6R(int, _intersect_point, const Vector3 &, uint32_t, bool, bool, GDExtensionPtr<PhysicsServer3DExtensionShapeResult>, int) - GDVIRTUAL9R(int, _intersect_shape, RID, const Transform3D &, const Vector3 &, real_t, uint32_t, bool, bool, GDExtensionPtr<PhysicsServer3DExtensionShapeResult>, int) - GDVIRTUAL10R(bool, _cast_motion, RID, const Transform3D &, const Vector3 &, real_t, uint32_t, bool, bool, GDExtensionPtr<real_t>, GDExtensionPtr<real_t>, GDExtensionPtr<PhysicsServer3DExtensionShapeRestInfo>) - GDVIRTUAL10R(bool, _collide_shape, RID, const Transform3D &, const Vector3 &, real_t, uint32_t, bool, bool, GDExtensionPtr<Vector3>, int, GDExtensionPtr<int>) - GDVIRTUAL8R(bool, _rest_info, RID, const Transform3D &, const Vector3 &, real_t, uint32_t, bool, bool, GDExtensionPtr<PhysicsServer3DExtensionShapeRestInfo>) - GDVIRTUAL2RC(Vector3, _get_closest_point_to_object_volume, RID, const Vector3 &) + GDVIRTUAL9R_REQUIRED(bool, _intersect_ray, const Vector3 &, const Vector3 &, uint32_t, bool, bool, bool, bool, bool, GDExtensionPtr<PhysicsServer3DExtensionRayResult>) + GDVIRTUAL6R_REQUIRED(int, _intersect_point, const Vector3 &, uint32_t, bool, bool, GDExtensionPtr<PhysicsServer3DExtensionShapeResult>, int) + GDVIRTUAL9R_REQUIRED(int, _intersect_shape, RID, const Transform3D &, const Vector3 &, real_t, uint32_t, bool, bool, GDExtensionPtr<PhysicsServer3DExtensionShapeResult>, int) + GDVIRTUAL10R_REQUIRED(bool, _cast_motion, RID, const Transform3D &, const Vector3 &, real_t, uint32_t, bool, bool, GDExtensionPtr<real_t>, GDExtensionPtr<real_t>, GDExtensionPtr<PhysicsServer3DExtensionShapeRestInfo>) + GDVIRTUAL10R_REQUIRED(bool, _collide_shape, RID, const Transform3D &, const Vector3 &, real_t, uint32_t, bool, bool, GDExtensionPtr<Vector3>, int, GDExtensionPtr<int>) + GDVIRTUAL8R_REQUIRED(bool, _rest_info, RID, const Transform3D &, const Vector3 &, real_t, uint32_t, bool, bool, GDExtensionPtr<PhysicsServer3DExtensionShapeRestInfo>) + GDVIRTUAL2RC_REQUIRED(Vector3, _get_closest_point_to_object_volume, RID, const Vector3 &) public: virtual bool intersect_ray(const RayParameters &p_parameters, RayResult &r_result) override { exclude = &p_parameters.exclude; bool ret = false; - GDVIRTUAL_REQUIRED_CALL(_intersect_ray, p_parameters.from, p_parameters.to, p_parameters.collision_mask, p_parameters.collide_with_bodies, p_parameters.collide_with_areas, p_parameters.hit_from_inside, p_parameters.hit_back_faces, p_parameters.pick_ray, &r_result, ret); + GDVIRTUAL_CALL(_intersect_ray, p_parameters.from, p_parameters.to, p_parameters.collision_mask, p_parameters.collide_with_bodies, p_parameters.collide_with_areas, p_parameters.hit_from_inside, p_parameters.hit_back_faces, p_parameters.pick_ray, &r_result, ret); exclude = nullptr; return ret; } virtual int intersect_point(const PointParameters &p_parameters, ShapeResult *r_results, int p_result_max) override { exclude = &p_parameters.exclude; int ret = false; - GDVIRTUAL_REQUIRED_CALL(_intersect_point, p_parameters.position, p_parameters.collision_mask, p_parameters.collide_with_bodies, p_parameters.collide_with_areas, r_results, p_result_max, ret); + GDVIRTUAL_CALL(_intersect_point, p_parameters.position, p_parameters.collision_mask, p_parameters.collide_with_bodies, p_parameters.collide_with_areas, r_results, p_result_max, ret); exclude = nullptr; return ret; } virtual int intersect_shape(const ShapeParameters &p_parameters, ShapeResult *r_results, int p_result_max) override { exclude = &p_parameters.exclude; int ret = 0; - GDVIRTUAL_REQUIRED_CALL(_intersect_shape, p_parameters.shape_rid, p_parameters.transform, p_parameters.motion, p_parameters.margin, p_parameters.collision_mask, p_parameters.collide_with_bodies, p_parameters.collide_with_areas, r_results, p_result_max, ret); + GDVIRTUAL_CALL(_intersect_shape, p_parameters.shape_rid, p_parameters.transform, p_parameters.motion, p_parameters.margin, p_parameters.collision_mask, p_parameters.collide_with_bodies, p_parameters.collide_with_areas, r_results, p_result_max, ret); exclude = nullptr; return ret; } virtual bool cast_motion(const ShapeParameters &p_parameters, real_t &p_closest_safe, real_t &p_closest_unsafe, ShapeRestInfo *r_info = nullptr) override { exclude = &p_parameters.exclude; bool ret = false; - GDVIRTUAL_REQUIRED_CALL(_cast_motion, p_parameters.shape_rid, p_parameters.transform, p_parameters.motion, p_parameters.margin, p_parameters.collision_mask, p_parameters.collide_with_bodies, p_parameters.collide_with_areas, &p_closest_safe, &p_closest_unsafe, r_info, ret); + GDVIRTUAL_CALL(_cast_motion, p_parameters.shape_rid, p_parameters.transform, p_parameters.motion, p_parameters.margin, p_parameters.collision_mask, p_parameters.collide_with_bodies, p_parameters.collide_with_areas, &p_closest_safe, &p_closest_unsafe, r_info, ret); exclude = nullptr; return ret; } virtual bool collide_shape(const ShapeParameters &p_parameters, Vector3 *r_results, int p_result_max, int &r_result_count) override { exclude = &p_parameters.exclude; bool ret = false; - GDVIRTUAL_REQUIRED_CALL(_collide_shape, p_parameters.shape_rid, p_parameters.transform, p_parameters.motion, p_parameters.margin, p_parameters.collision_mask, p_parameters.collide_with_bodies, p_parameters.collide_with_areas, r_results, p_result_max, &r_result_count, ret); + GDVIRTUAL_CALL(_collide_shape, p_parameters.shape_rid, p_parameters.transform, p_parameters.motion, p_parameters.margin, p_parameters.collision_mask, p_parameters.collide_with_bodies, p_parameters.collide_with_areas, r_results, p_result_max, &r_result_count, ret); exclude = nullptr; return ret; } virtual bool rest_info(const ShapeParameters &p_parameters, ShapeRestInfo *r_info) override { exclude = &p_parameters.exclude; bool ret = false; - GDVIRTUAL_REQUIRED_CALL(_rest_info, p_parameters.shape_rid, p_parameters.transform, p_parameters.motion, p_parameters.margin, p_parameters.collision_mask, p_parameters.collide_with_bodies, p_parameters.collide_with_areas, r_info, ret); + GDVIRTUAL_CALL(_rest_info, p_parameters.shape_rid, p_parameters.transform, p_parameters.motion, p_parameters.margin, p_parameters.collision_mask, p_parameters.collide_with_bodies, p_parameters.collide_with_areas, r_info, ret); exclude = nullptr; return ret; } virtual Vector3 get_closest_point_to_object_volume(RID p_object, const Vector3 p_point) const override { Vector3 ret; - GDVIRTUAL_REQUIRED_CALL(_get_closest_point_to_object_volume, p_object, p_point, ret); + GDVIRTUAL_CALL(_get_closest_point_to_object_volume, p_object, p_point, ret); return ret; } @@ -359,11 +359,11 @@ public: EXBIND2(body_add_collision_exception, RID, RID) EXBIND2(body_remove_collision_exception, RID, RID) - GDVIRTUAL1RC(TypedArray<RID>, _body_get_collision_exceptions, RID) + GDVIRTUAL1RC_REQUIRED(TypedArray<RID>, _body_get_collision_exceptions, RID) void body_get_collision_exceptions(RID p_body, List<RID> *p_exceptions) override { TypedArray<RID> ret; - GDVIRTUAL_REQUIRED_CALL(_body_get_collision_exceptions, p_body, ret); + GDVIRTUAL_CALL(_body_get_collision_exceptions, p_body, ret); for (int i = 0; i < ret.size(); i++) { p_exceptions->push_back(ret[i]); } @@ -383,7 +383,7 @@ public: EXBIND2(body_set_ray_pickable, RID, bool) - GDVIRTUAL8RC(bool, _body_test_motion, RID, const Transform3D &, const Vector3 &, real_t, int, bool, bool, GDExtensionPtr<PhysicsServer3DExtensionMotionResult>) + GDVIRTUAL8RC_REQUIRED(bool, _body_test_motion, RID, const Transform3D &, const Vector3 &, real_t, int, bool, bool, GDExtensionPtr<PhysicsServer3DExtensionMotionResult>) thread_local static const HashSet<RID> *exclude_bodies; thread_local static const HashSet<ObjectID> *exclude_objects; @@ -395,7 +395,7 @@ public: bool ret = false; exclude_bodies = &p_parameters.exclude_bodies; exclude_objects = &p_parameters.exclude_objects; - GDVIRTUAL_REQUIRED_CALL(_body_test_motion, p_body, p_parameters.from, p_parameters.motion, p_parameters.margin, p_parameters.max_collisions, p_parameters.collide_separation_ray, p_parameters.recovery_as_collision, r_result, ret); + GDVIRTUAL_CALL(_body_test_motion, p_body, p_parameters.from, p_parameters.motion, p_parameters.margin, p_parameters.max_collisions, p_parameters.collide_separation_ray, p_parameters.recovery_as_collision, r_result, ret); exclude_bodies = nullptr; exclude_objects = nullptr; return ret; @@ -423,11 +423,11 @@ public: EXBIND2(soft_body_add_collision_exception, RID, RID) EXBIND2(soft_body_remove_collision_exception, RID, RID) - GDVIRTUAL1RC(TypedArray<RID>, _soft_body_get_collision_exceptions, RID) + GDVIRTUAL1RC_REQUIRED(TypedArray<RID>, _soft_body_get_collision_exceptions, RID) void soft_body_get_collision_exceptions(RID p_soft_body, List<RID> *p_exceptions) override { TypedArray<RID> ret; - GDVIRTUAL_REQUIRED_CALL(_soft_body_get_collision_exceptions, p_soft_body, ret); + GDVIRTUAL_CALL(_soft_body_get_collision_exceptions, p_soft_body, ret); for (int i = 0; i < ret.size(); i++) { p_exceptions->push_back(ret[i]); } @@ -520,9 +520,9 @@ public: /* MISC */ - GDVIRTUAL1(_free_rid, RID) + GDVIRTUAL1_REQUIRED(_free_rid, RID) virtual void free(RID p_rid) override { - GDVIRTUAL_REQUIRED_CALL(_free_rid, p_rid); + GDVIRTUAL_CALL(_free_rid, p_rid); } EXBIND1(set_active, bool) diff --git a/servers/movie_writer/movie_writer.cpp b/servers/movie_writer/movie_writer.cpp index aebed4b432..14e920d8cd 100644 --- a/servers/movie_writer/movie_writer.cpp +++ b/servers/movie_writer/movie_writer.cpp @@ -54,40 +54,40 @@ MovieWriter *MovieWriter::find_writer_for_file(const String &p_file) { uint32_t MovieWriter::get_audio_mix_rate() const { uint32_t ret = 48000; - GDVIRTUAL_REQUIRED_CALL(_get_audio_mix_rate, ret); + GDVIRTUAL_CALL(_get_audio_mix_rate, ret); return ret; } AudioServer::SpeakerMode MovieWriter::get_audio_speaker_mode() const { AudioServer::SpeakerMode ret = AudioServer::SPEAKER_MODE_STEREO; - GDVIRTUAL_REQUIRED_CALL(_get_audio_speaker_mode, ret); + GDVIRTUAL_CALL(_get_audio_speaker_mode, ret); return ret; } Error MovieWriter::write_begin(const Size2i &p_movie_size, uint32_t p_fps, const String &p_base_path) { Error ret = ERR_UNCONFIGURED; - GDVIRTUAL_REQUIRED_CALL(_write_begin, p_movie_size, p_fps, p_base_path, ret); + GDVIRTUAL_CALL(_write_begin, p_movie_size, p_fps, p_base_path, ret); return ret; } Error MovieWriter::write_frame(const Ref<Image> &p_image, const int32_t *p_audio_data) { Error ret = ERR_UNCONFIGURED; - GDVIRTUAL_REQUIRED_CALL(_write_frame, p_image, p_audio_data, ret); + GDVIRTUAL_CALL(_write_frame, p_image, p_audio_data, ret); return ret; } void MovieWriter::write_end() { - GDVIRTUAL_REQUIRED_CALL(_write_end); + GDVIRTUAL_CALL(_write_end); } bool MovieWriter::handles_file(const String &p_path) const { bool ret = false; - GDVIRTUAL_REQUIRED_CALL(_handles_file, p_path, ret); + GDVIRTUAL_CALL(_handles_file, p_path, ret); return ret; } void MovieWriter::get_supported_extensions(List<String> *r_extensions) const { Vector<String> exts; - GDVIRTUAL_REQUIRED_CALL(_get_supported_extensions, exts); + GDVIRTUAL_CALL(_get_supported_extensions, exts); for (int i = 0; i < exts.size(); i++) { r_extensions->push_back(exts[i]); } diff --git a/servers/movie_writer/movie_writer.h b/servers/movie_writer/movie_writer.h index 4757de203c..e1dc8ef8cf 100644 --- a/servers/movie_writer/movie_writer.h +++ b/servers/movie_writer/movie_writer.h @@ -63,15 +63,15 @@ protected: virtual Error write_frame(const Ref<Image> &p_image, const int32_t *p_audio_data); virtual void write_end(); - GDVIRTUAL0RC(uint32_t, _get_audio_mix_rate) - GDVIRTUAL0RC(AudioServer::SpeakerMode, _get_audio_speaker_mode) + GDVIRTUAL0RC_REQUIRED(uint32_t, _get_audio_mix_rate) + GDVIRTUAL0RC_REQUIRED(AudioServer::SpeakerMode, _get_audio_speaker_mode) - GDVIRTUAL1RC(bool, _handles_file, const String &) - GDVIRTUAL0RC(Vector<String>, _get_supported_extensions) + GDVIRTUAL1RC_REQUIRED(bool, _handles_file, const String &) + GDVIRTUAL0RC_REQUIRED(Vector<String>, _get_supported_extensions) - GDVIRTUAL3R(Error, _write_begin, const Size2i &, uint32_t, const String &) - GDVIRTUAL2R(Error, _write_frame, const Ref<Image> &, GDExtensionConstPtr<int32_t>) - GDVIRTUAL0(_write_end) + GDVIRTUAL3R_REQUIRED(Error, _write_begin, const Size2i &, uint32_t, const String &) + GDVIRTUAL2R_REQUIRED(Error, _write_frame, const Ref<Image> &, GDExtensionConstPtr<int32_t>) + GDVIRTUAL0_REQUIRED(_write_end) static void _bind_methods(); diff --git a/servers/physics_server_3d.cpp b/servers/physics_server_3d.cpp index ee48151863..312b67ada9 100644 --- a/servers/physics_server_3d.cpp +++ b/servers/physics_server_3d.cpp @@ -37,13 +37,13 @@ #include "core/variant/typed_array.h" void PhysicsServer3DRenderingServerHandler::set_vertex(int p_vertex_id, const Vector3 &p_vertex) { - GDVIRTUAL_REQUIRED_CALL(_set_vertex, p_vertex_id, p_vertex); + GDVIRTUAL_CALL(_set_vertex, p_vertex_id, p_vertex); } void PhysicsServer3DRenderingServerHandler::set_normal(int p_vertex_id, const Vector3 &p_normal) { - GDVIRTUAL_REQUIRED_CALL(_set_normal, p_vertex_id, p_normal); + GDVIRTUAL_CALL(_set_normal, p_vertex_id, p_normal); } void PhysicsServer3DRenderingServerHandler::set_aabb(const AABB &p_aabb) { - GDVIRTUAL_REQUIRED_CALL(_set_aabb, p_aabb); + GDVIRTUAL_CALL(_set_aabb, p_aabb); } void PhysicsServer3DRenderingServerHandler::_bind_methods() { diff --git a/servers/physics_server_3d.h b/servers/physics_server_3d.h index ea785fa03f..33def7cf8d 100644 --- a/servers/physics_server_3d.h +++ b/servers/physics_server_3d.h @@ -213,9 +213,9 @@ public: class PhysicsServer3DRenderingServerHandler : public Object { GDCLASS(PhysicsServer3DRenderingServerHandler, Object) protected: - GDVIRTUAL2(_set_vertex, int, const Vector3 &) - GDVIRTUAL2(_set_normal, int, const Vector3 &) - GDVIRTUAL1(_set_aabb, const AABB &) + GDVIRTUAL2_REQUIRED(_set_vertex, int, const Vector3 &) + GDVIRTUAL2_REQUIRED(_set_normal, int, const Vector3 &) + GDVIRTUAL1_REQUIRED(_set_aabb, const AABB &) static void _bind_methods(); 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 aca85ce497..307898232d 100644 --- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp +++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp @@ -4261,6 +4261,11 @@ RenderForwardClustered::RenderForwardClustered() { defines += "\n#define SDFGI_OCT_SIZE " + itos(gi.sdfgi_get_lightprobe_octahedron_size()) + "\n"; defines += "\n#define MAX_DIRECTIONAL_LIGHT_DATA_STRUCTS " + itos(MAX_DIRECTIONAL_LIGHTS) + "\n"; + bool force_vertex_shading = GLOBAL_GET("rendering/shading/overrides/force_vertex_shading"); + if (force_vertex_shading) { + defines += "\n#define USE_VERTEX_LIGHTING\n"; + } + { //lightmaps scene_state.max_lightmaps = MAX_LIGHTMAPS; 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 6846c3f693..ee5b5ef1d8 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 @@ -730,13 +730,20 @@ void SceneShaderForwardClustered::init(const String p_defines) { actions.render_mode_defines["ambient_light_disabled"] = "#define AMBIENT_LIGHT_DISABLED\n"; actions.render_mode_defines["shadow_to_opacity"] = "#define USE_SHADOW_TO_OPACITY\n"; actions.render_mode_defines["unshaded"] = "#define MODE_UNSHADED\n"; + + bool force_vertex_shading = GLOBAL_GET("rendering/shading/overrides/force_vertex_shading"); + if (!force_vertex_shading) { + // If forcing vertex shading, this will be defined already. + actions.render_mode_defines["vertex_lighting"] = "#define USE_VERTEX_LIGHTING\n"; + } + actions.render_mode_defines["debug_shadow_splits"] = "#define DEBUG_DRAW_PSSM_SPLITS\n"; actions.render_mode_defines["fog_disabled"] = "#define FOG_DISABLED\n"; actions.base_texture_binding_index = 1; actions.texture_layout_set = RenderForwardClustered::MATERIAL_UNIFORM_SET; actions.base_uniform_string = "material."; - actions.base_varying_index = 12; + actions.base_varying_index = 14; actions.default_filter = ShaderLanguage::FILTER_LINEAR_MIPMAP; actions.default_repeat = ShaderLanguage::REPEAT_ENABLE; 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 8a02ec0eb5..fa8796fae6 100644 --- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp +++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp @@ -2800,6 +2800,11 @@ RenderForwardMobile::RenderForwardMobile() { // defines += "\n#define SDFGI_OCT_SIZE " + itos(gi.sdfgi_get_lightprobe_octahedron_size()) + "\n"; defines += "\n#define MAX_DIRECTIONAL_LIGHT_DATA_STRUCTS " + itos(MAX_DIRECTIONAL_LIGHTS) + "\n"; + bool force_vertex_shading = GLOBAL_GET("rendering/shading/overrides/force_vertex_shading"); + if (force_vertex_shading) { + defines += "\n#define USE_VERTEX_LIGHTING\n"; + } + { //lightmaps scene_state.max_lightmaps = 2; 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 08982096c5..5dec4d8f21 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 @@ -633,6 +633,13 @@ void SceneShaderForwardMobile::init(const String p_defines) { actions.render_mode_defines["ambient_light_disabled"] = "#define AMBIENT_LIGHT_DISABLED\n"; actions.render_mode_defines["shadow_to_opacity"] = "#define USE_SHADOW_TO_OPACITY\n"; actions.render_mode_defines["unshaded"] = "#define MODE_UNSHADED\n"; + + bool force_vertex_shading = GLOBAL_GET("rendering/shading/overrides/force_vertex_shading"); + if (!force_vertex_shading) { + // If forcing vertex shading, this will be defined already. + actions.render_mode_defines["vertex_lighting"] = "#define USE_VERTEX_LIGHTING\n"; + } + actions.render_mode_defines["debug_shadow_splits"] = "#define DEBUG_DRAW_PSSM_SPLITS\n"; actions.render_mode_defines["fog_disabled"] = "#define FOG_DISABLED\n"; diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp index 57497eb207..5441e28be0 100644 --- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp @@ -1974,6 +1974,12 @@ RendererCanvasRenderRD::RendererCanvasRenderRD() { default_canvas_texture = texture_storage->canvas_texture_allocate(); texture_storage->canvas_texture_initialize(default_canvas_texture); + RendererRD::TextureStorage::CanvasTextureInfo info = RendererRD::TextureStorage::get_singleton()->canvas_texture_get_info(default_canvas_texture, default_filter, default_repeat, false, false); + default_texture_info.diffuse = info.diffuse; + default_texture_info.normal = info.normal; + default_texture_info.specular = info.specular; + default_texture_info.sampler = info.sampler; + state.shadow_texture_size = GLOBAL_GET("rendering/2d/shadow_atlas/size"); //create functions for shader and material @@ -2219,7 +2225,7 @@ void RendererCanvasRenderRD::_render_batch_items(RenderTarget p_to_render_target RD::get_singleton()->draw_list_bind_uniform_set(draw_list, state.default_transforms_uniform_set, TRANSFORMS_UNIFORM_SET); Item *current_clip = nullptr; - state.current_tex_uniform_set = RID(); + state.current_batch_uniform_set = RID(); for (uint32_t i = 0; i <= state.current_batch_index; i++) { Batch *current_batch = &state.canvas_instance_batches[i]; @@ -2337,11 +2343,11 @@ void RendererCanvasRenderRD::_record_item_commands(const Item *p_item, RenderTar instance_data->world[i] = world[i]; } - instance_data->flags = base_flags | r_current_batch->tex_flags; // Reset on each command for safety, keep canvas texture binding config. + instance_data->flags = base_flags | r_current_batch->tex_info.flags; // Reset on each command for safety, keep canvas texture binding config. - instance_data->color_texture_pixel_size[0] = r_current_batch->tex_texpixel_size.width; - instance_data->color_texture_pixel_size[1] = r_current_batch->tex_texpixel_size.height; - instance_data->specular_shininess = r_current_batch->tex_specular_shininess; + instance_data->color_texture_pixel_size[0] = r_current_batch->tex_info.texpixel_size.width; + instance_data->color_texture_pixel_size[1] = r_current_batch->tex_info.texpixel_size.height; + instance_data->specular_shininess = r_current_batch->tex_info.specular_shininess; return instance_data; }; @@ -2373,10 +2379,10 @@ void RendererCanvasRenderRD::_record_item_commands(const Item *p_item, RenderTar bool has_msdf = bool(rect->flags & CANVAS_RECT_MSDF); TextureState tex_state(rect->texture, texture_filter, texture_repeat, has_msdf, use_linear_colors); - if (tex_state != r_current_batch->tex_state) { + if (tex_state != r_current_batch->tex_info.state) { r_current_batch = _new_batch(r_batch_broken); - r_current_batch->set_tex_state(tex_state); - _prepare_batch_texture(r_current_batch, rect->texture); + r_current_batch->tex_info.state = tex_state; + _prepare_batch_texture_info(r_current_batch, rect->texture); } Color modulated = rect->modulate * base_color; @@ -2399,7 +2405,7 @@ void RendererCanvasRenderRD::_record_item_commands(const Item *p_item, RenderTar Rect2 dst_rect; if (rect->texture.is_valid()) { - src_rect = (rect->flags & CANVAS_RECT_REGION) ? Rect2(rect->source.position * r_current_batch->tex_texpixel_size, rect->source.size * r_current_batch->tex_texpixel_size) : Rect2(0, 0, 1, 1); + src_rect = (rect->flags & CANVAS_RECT_REGION) ? Rect2(rect->source.position * r_current_batch->tex_info.texpixel_size, rect->source.size * r_current_batch->tex_info.texpixel_size) : Rect2(0, 0, 1, 1); dst_rect = Rect2(rect->rect.position, rect->rect.size); if (dst_rect.size.width < 0) { @@ -2484,10 +2490,10 @@ void RendererCanvasRenderRD::_record_item_commands(const Item *p_item, RenderTar } TextureState tex_state(np->texture, texture_filter, texture_repeat, false, use_linear_colors); - if (tex_state != r_current_batch->tex_state) { + if (tex_state != r_current_batch->tex_info.state) { r_current_batch = _new_batch(r_batch_broken); - r_current_batch->set_tex_state(tex_state); - _prepare_batch_texture(r_current_batch, np->texture); + r_current_batch->tex_info.state = tex_state; + _prepare_batch_texture_info(r_current_batch, np->texture); } InstanceData *instance_data = new_instance_data(); @@ -2499,7 +2505,7 @@ void RendererCanvasRenderRD::_record_item_commands(const Item *p_item, RenderTar src_rect = Rect2(0, 0, 1, 1); } else { if (np->source != Rect2()) { - src_rect = Rect2(np->source.position.x * r_current_batch->tex_texpixel_size.width, np->source.position.y * r_current_batch->tex_texpixel_size.height, np->source.size.x * r_current_batch->tex_texpixel_size.width, np->source.size.y * r_current_batch->tex_texpixel_size.height); + src_rect = Rect2(np->source.position.x * r_current_batch->tex_info.texpixel_size.width, np->source.position.y * r_current_batch->tex_info.texpixel_size.height, np->source.size.x * r_current_batch->tex_info.texpixel_size.width, np->source.size.y * r_current_batch->tex_info.texpixel_size.height); instance_data->color_texture_pixel_size[0] = 1.0 / np->source.size.width; instance_data->color_texture_pixel_size[1] = 1.0 / np->source.size.height; } else { @@ -2553,10 +2559,10 @@ void RendererCanvasRenderRD::_record_item_commands(const Item *p_item, RenderTar r_current_batch->command = c; TextureState tex_state(polygon->texture, texture_filter, texture_repeat, false, use_linear_colors); - if (tex_state != r_current_batch->tex_state) { + if (tex_state != r_current_batch->tex_info.state) { r_current_batch = _new_batch(r_batch_broken); - r_current_batch->set_tex_state(tex_state); - _prepare_batch_texture(r_current_batch, polygon->texture); + r_current_batch->tex_info.state = tex_state; + _prepare_batch_texture_info(r_current_batch, polygon->texture); } // pipeline variant @@ -2596,10 +2602,10 @@ void RendererCanvasRenderRD::_record_item_commands(const Item *p_item, RenderTar r_current_batch->pipeline_variant = variant[primitive->point_count - 1]; TextureState tex_state(primitive->texture, texture_filter, texture_repeat, false, use_linear_colors); - if (tex_state != r_current_batch->tex_state) { + if (tex_state != r_current_batch->tex_info.state) { r_current_batch = _new_batch(r_batch_broken); - r_current_batch->set_tex_state(tex_state); - _prepare_batch_texture(r_current_batch, primitive->texture); + r_current_batch->tex_info.state = tex_state; + _prepare_batch_texture_info(r_current_batch, primitive->texture); } } @@ -2657,8 +2663,8 @@ void RendererCanvasRenderRD::_record_item_commands(const Item *p_item, RenderTar if (c->type == Item::Command::TYPE_MESH) { const Item::CommandMesh *m = static_cast<const Item::CommandMesh *>(c); TextureState tex_state(m->texture, texture_filter, texture_repeat, false, use_linear_colors); - r_current_batch->set_tex_state(tex_state); - _prepare_batch_texture(r_current_batch, m->texture); + r_current_batch->tex_info.state = tex_state; + _prepare_batch_texture_info(r_current_batch, m->texture); instance_data = new_instance_data(); r_current_batch->mesh_instance_count = 1; @@ -2680,8 +2686,8 @@ void RendererCanvasRenderRD::_record_item_commands(const Item *p_item, RenderTar } TextureState tex_state(mm->texture, texture_filter, texture_repeat, false, use_linear_colors); - r_current_batch->set_tex_state(tex_state); - _prepare_batch_texture(r_current_batch, mm->texture); + r_current_batch->tex_info.state = tex_state; + _prepare_batch_texture_info(r_current_batch, mm->texture); instance_data = new_instance_data(); instance_data->flags |= 1; // multimesh, trails disabled @@ -2698,8 +2704,8 @@ void RendererCanvasRenderRD::_record_item_commands(const Item *p_item, RenderTar const Item::CommandParticles *pt = static_cast<const Item::CommandParticles *>(c); TextureState tex_state(pt->texture, texture_filter, texture_repeat, false, use_linear_colors); - r_current_batch->set_tex_state(tex_state); - _prepare_batch_texture(r_current_batch, pt->texture); + r_current_batch->tex_info.state = tex_state; + _prepare_batch_texture_info(r_current_batch, pt->texture); instance_data = new_instance_data(); @@ -2795,7 +2801,20 @@ void RendererCanvasRenderRD::_render_batch(RD::DrawListID p_draw_list, PipelineV ERR_FAIL_NULL(p_batch->command); - _bind_canvas_texture(p_draw_list, p_batch->tex_uniform_set); + { + RD::Uniform u_diffuse(RD::UNIFORM_TYPE_TEXTURE, 0, p_batch->tex_info.diffuse); + RD::Uniform u_normal(RD::UNIFORM_TYPE_TEXTURE, 1, p_batch->tex_info.normal); + RD::Uniform u_specular(RD::UNIFORM_TYPE_TEXTURE, 2, p_batch->tex_info.specular); + RD::Uniform u_sampler(RD::UNIFORM_TYPE_SAMPLER, 3, p_batch->tex_info.sampler); + RD::Uniform u_instance_data(RD::UNIFORM_TYPE_STORAGE_BUFFER, 4, state.canvas_instance_data_buffers[state.current_data_buffer_index].instance_buffers[p_batch->instance_buffer_index]); + + RID uniform_set = uniform_set_cache->get_cache(shader.default_version_rd_shader, BATCH_UNIFORM_SET, u_diffuse, u_normal, u_specular, u_sampler, u_instance_data); + + if (state.current_batch_uniform_set != uniform_set) { + state.current_batch_uniform_set = uniform_set; + RD::get_singleton()->draw_list_bind_uniform_set(p_draw_list, uniform_set, BATCH_UNIFORM_SET); + } + } switch (p_batch->command_type) { case Item::Command::TYPE_RECT: @@ -2810,13 +2829,6 @@ void RendererCanvasRenderRD::_render_batch(RD::DrawListID p_draw_list, PipelineV PushConstant push_constant; push_constant.base_instance_index = p_batch->start; RD::get_singleton()->draw_list_set_push_constant(p_draw_list, &push_constant, sizeof(PushConstant)); - - RD::Uniform u_instance_data(RD::UNIFORM_TYPE_STORAGE_BUFFER, 0, state.canvas_instance_data_buffers[state.current_data_buffer_index].instance_buffers[p_batch->instance_buffer_index]); - RD::get_singleton()->draw_list_bind_uniform_set( - p_draw_list, - uniform_set_cache->get_cache(shader.default_version_rd_shader, INSTANCE_DATA_UNIFORM_SET, u_instance_data), - INSTANCE_DATA_UNIFORM_SET); - RD::get_singleton()->draw_list_bind_index_array(p_draw_list, shader.quad_index_array); RD::get_singleton()->draw_list_draw(p_draw_list, true, p_batch->instance_count); @@ -2839,13 +2851,6 @@ void RendererCanvasRenderRD::_render_batch(RD::DrawListID p_draw_list, PipelineV PushConstant push_constant; push_constant.base_instance_index = p_batch->start; RD::get_singleton()->draw_list_set_push_constant(p_draw_list, &push_constant, sizeof(PushConstant)); - - RD::Uniform u_instance_data(RD::UNIFORM_TYPE_STORAGE_BUFFER, 0, state.canvas_instance_data_buffers[state.current_data_buffer_index].instance_buffers[p_batch->instance_buffer_index]); - RD::get_singleton()->draw_list_bind_uniform_set( - p_draw_list, - uniform_set_cache->get_cache(shader.default_version_rd_shader, INSTANCE_DATA_UNIFORM_SET, u_instance_data), - INSTANCE_DATA_UNIFORM_SET); - RD::get_singleton()->draw_list_bind_vertex_array(p_draw_list, pb->vertex_array); if (pb->indices.is_valid()) { RD::get_singleton()->draw_list_bind_index_array(p_draw_list, pb->indices); @@ -2868,13 +2873,6 @@ void RendererCanvasRenderRD::_render_batch(RD::DrawListID p_draw_list, PipelineV PushConstant push_constant; push_constant.base_instance_index = p_batch->start; RD::get_singleton()->draw_list_set_push_constant(p_draw_list, &push_constant, sizeof(PushConstant)); - - RD::Uniform u_instance_data(RD::UNIFORM_TYPE_STORAGE_BUFFER, 0, state.canvas_instance_data_buffers[state.current_data_buffer_index].instance_buffers[p_batch->instance_buffer_index]); - RD::get_singleton()->draw_list_bind_uniform_set( - p_draw_list, - uniform_set_cache->get_cache(shader.default_version_rd_shader, INSTANCE_DATA_UNIFORM_SET, u_instance_data), - INSTANCE_DATA_UNIFORM_SET); - RD::get_singleton()->draw_list_bind_index_array(p_draw_list, primitive_arrays.index_array[MIN(3u, primitive->point_count) - 1]); uint32_t instance_count = p_batch->instance_count; RD::get_singleton()->draw_list_draw(p_draw_list, true, instance_count); @@ -2934,12 +2932,6 @@ void RendererCanvasRenderRD::_render_batch(RD::DrawListID p_draw_list, PipelineV break; } - RD::Uniform u_instance_data(RD::UNIFORM_TYPE_STORAGE_BUFFER, 0, state.canvas_instance_data_buffers[state.current_data_buffer_index].instance_buffers[p_batch->instance_buffer_index]); - RD::get_singleton()->draw_list_bind_uniform_set( - p_draw_list, - uniform_set_cache->get_cache(shader.default_version_rd_shader, INSTANCE_DATA_UNIFORM_SET, u_instance_data), - INSTANCE_DATA_UNIFORM_SET); - uint32_t surf_count = mesh_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 }; @@ -3046,60 +3038,46 @@ void RendererCanvasRenderRD::_allocate_instance_buffer() { state.canvas_instance_data_buffers[state.current_data_buffer_index].instance_buffers.push_back(buf); } -void RendererCanvasRenderRD::_prepare_batch_texture(Batch *p_current_batch, RID p_texture) const { +void RendererCanvasRenderRD::_prepare_batch_texture_info(Batch *p_current_batch, RID p_texture) const { if (p_texture.is_null()) { p_texture = default_canvas_texture; } - Color specular_shininess; - bool use_normal; - bool use_specular; - Size2i size; - bool success = RendererRD::TextureStorage::get_singleton()->canvas_texture_get_uniform_set( - p_texture, - p_current_batch->tex_state.texture_filter(), - p_current_batch->tex_state.texture_repeat(), - shader.default_version_rd_shader, - CANVAS_TEXTURE_UNIFORM_SET, - p_current_batch->tex_state.linear_colors(), - p_current_batch->tex_uniform_set, - size, - specular_shininess, - use_normal, - use_specular, - p_current_batch->tex_state.texture_is_data()); + RendererRD::TextureStorage::CanvasTextureInfo info = + RendererRD::TextureStorage::get_singleton()->canvas_texture_get_info( + p_texture, + p_current_batch->tex_info.state.texture_filter(), + p_current_batch->tex_info.state.texture_repeat(), + p_current_batch->tex_info.state.linear_colors(), + p_current_batch->tex_info.state.texture_is_data()); + // something odd happened - if (!success) { - _prepare_batch_texture(p_current_batch, default_canvas_texture); + if (info.is_null()) { + _prepare_batch_texture_info(p_current_batch, default_canvas_texture); return; } - // cache values to be copied to instance data - if (specular_shininess.a < 0.999) { - p_current_batch->tex_flags |= FLAGS_DEFAULT_SPECULAR_MAP_USED; - } + p_current_batch->tex_info.diffuse = info.diffuse; + p_current_batch->tex_info.normal = info.normal; + p_current_batch->tex_info.specular = info.specular; + p_current_batch->tex_info.sampler = info.sampler; - if (use_normal) { - p_current_batch->tex_flags |= FLAGS_DEFAULT_NORMAL_MAP_USED; + // cache values to be copied to instance data + if (info.specular_color.a < 0.999) { + p_current_batch->tex_info.flags |= FLAGS_DEFAULT_SPECULAR_MAP_USED; } - uint8_t a = uint8_t(CLAMP(specular_shininess.a * 255.0, 0.0, 255.0)); - uint8_t b = uint8_t(CLAMP(specular_shininess.b * 255.0, 0.0, 255.0)); - uint8_t g = uint8_t(CLAMP(specular_shininess.g * 255.0, 0.0, 255.0)); - uint8_t r = uint8_t(CLAMP(specular_shininess.r * 255.0, 0.0, 255.0)); - p_current_batch->tex_specular_shininess = uint32_t(a) << 24 | uint32_t(b) << 16 | uint32_t(g) << 8 | uint32_t(r); - - p_current_batch->tex_texpixel_size = Vector2(1.0 / float(size.width), 1.0 / float(size.height)); -} - -void RendererCanvasRenderRD::_bind_canvas_texture(RD::DrawListID p_draw_list, RID p_uniform_set) { - if (state.current_tex_uniform_set == p_uniform_set) { - return; + if (info.use_normal) { + p_current_batch->tex_info.flags |= FLAGS_DEFAULT_NORMAL_MAP_USED; } - state.current_tex_uniform_set = p_uniform_set; + uint8_t a = uint8_t(CLAMP(info.specular_color.a * 255.0, 0.0, 255.0)); + uint8_t b = uint8_t(CLAMP(info.specular_color.b * 255.0, 0.0, 255.0)); + uint8_t g = uint8_t(CLAMP(info.specular_color.g * 255.0, 0.0, 255.0)); + uint8_t r = uint8_t(CLAMP(info.specular_color.r * 255.0, 0.0, 255.0)); + p_current_batch->tex_info.specular_shininess = uint32_t(a) << 24 | uint32_t(b) << 16 | uint32_t(g) << 8 | uint32_t(r); - RD::get_singleton()->draw_list_bind_uniform_set(p_draw_list, p_uniform_set, CANVAS_TEXTURE_UNIFORM_SET); + p_current_batch->tex_info.texpixel_size = Vector2(1.0 / float(info.size.width), 1.0 / float(info.size.height)); } RendererCanvasRenderRD::~RendererCanvasRenderRD() { diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.h b/servers/rendering/renderer_rd/renderer_canvas_render_rd.h index 8d90cd23ce..b0f4a4595a 100644 --- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.h +++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.h @@ -45,8 +45,7 @@ class RendererCanvasRenderRD : public RendererCanvasRender { BASE_UNIFORM_SET = 0, MATERIAL_UNIFORM_SET = 1, TRANSFORMS_UNIFORM_SET = 2, - CANVAS_TEXTURE_UNIFORM_SET = 3, - INSTANCE_DATA_UNIFORM_SET = 4, + BATCH_UNIFORM_SET = 3, }; const int SAMPLERS_BINDING_FIRST_INDEX = 10; @@ -423,24 +422,25 @@ class RendererCanvasRenderRD : public RendererCanvasRender { } }; + struct TextureInfo { + TextureState state; + uint32_t specular_shininess = 0; + uint32_t flags = 0; + Vector2 texpixel_size; + + RID diffuse; + RID normal; + RID specular; + RID sampler; + }; + struct Batch { // Position in the UBO measured in bytes uint32_t start = 0; uint32_t instance_count = 0; uint32_t instance_buffer_index = 0; - TextureState tex_state; - RID tex_uniform_set; - - // The following tex_ prefixed fields are used to cache the texture data for the current batch. - // These values are applied to new InstanceData for the batch - - // The cached specular shininess derived from the current texture. - uint32_t tex_specular_shininess = 0; - // The cached texture flags, such as FLAGS_DEFAULT_SPECULAR_MAP_USED and FLAGS_DEFAULT_NORMAL_MAP_USED - uint32_t tex_flags = 0; - // The cached texture pixel size. - Vector2 tex_texpixel_size; + TextureInfo tex_info; Color modulate = Color(1.0, 1.0, 1.0, 1.0); @@ -462,14 +462,6 @@ class RendererCanvasRenderRD : public RendererCanvasRender { uint32_t mesh_instance_count; }; bool has_blend = false; - - void set_tex_state(TextureState &p_tex_state) { - tex_state = p_tex_state; - tex_uniform_set = RID(); - tex_texpixel_size = Size2(); - tex_specular_shininess = 0; - tex_flags = 0; - } }; struct DataBuffer { @@ -509,7 +501,7 @@ class RendererCanvasRenderRD : public RendererCanvasRender { uint32_t max_instances_per_buffer = 16384; uint32_t max_instance_buffer_size = 16384 * sizeof(InstanceData); - RID current_tex_uniform_set; + RID current_batch_uniform_set; LightUniform *light_uniforms = nullptr; @@ -532,6 +524,8 @@ class RendererCanvasRenderRD : public RendererCanvasRender { Item *items[MAX_RENDER_ITEMS]; + TextureInfo default_texture_info; + bool using_directional_lights = false; RID default_canvas_texture; @@ -561,8 +555,7 @@ class RendererCanvasRenderRD : public RendererCanvasRender { void _render_batch_items(RenderTarget p_to_render_target, int p_item_count, const Transform2D &p_canvas_transform_inverse, Light *p_lights, bool &r_sdf_used, bool p_to_backbuffer = false, RenderingMethod::RenderInfo *r_render_info = nullptr); void _record_item_commands(const Item *p_item, RenderTarget p_render_target, const Transform2D &p_base_transform, Item *&r_current_clip, Light *p_lights, uint32_t &r_index, bool &r_batch_broken, bool &r_sdf_used, Batch *&r_current_batch); void _render_batch(RD::DrawListID p_draw_list, PipelineVariants *p_pipeline_variants, RenderingDevice::FramebufferFormatID p_framebuffer_format, Light *p_lights, Batch const *p_batch, RenderingMethod::RenderInfo *r_render_info = nullptr); - void _prepare_batch_texture(Batch *p_current_batch, RID p_texture) const; - void _bind_canvas_texture(RD::DrawListID p_draw_list, RID p_uniform_set); + void _prepare_batch_texture_info(Batch *p_current_batch, RID p_texture) const; [[nodiscard]] Batch *_new_batch(bool &r_batch_broken); void _add_to_batch(uint32_t &r_index, bool &r_batch_broken, Batch *&r_current_batch); void _allocate_instance_buffer(); diff --git a/servers/rendering/renderer_rd/shaders/canvas_uniforms_inc.glsl b/servers/rendering/renderer_rd/shaders/canvas_uniforms_inc.glsl index 7cf5b4576e..fc9b727581 100644 --- a/servers/rendering/renderer_rd/shaders/canvas_uniforms_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/canvas_uniforms_inc.glsl @@ -54,11 +54,6 @@ struct InstanceData { uint lights[4]; }; -layout(set = 4, binding = 0, std430) restrict readonly buffer DrawData { - InstanceData data[]; -} -instances; - layout(push_constant, std430) uniform Params { uint base_instance_index; // base index to instance data uint pad1; @@ -163,3 +158,8 @@ layout(set = 3, binding = 0) uniform texture2D color_texture; layout(set = 3, binding = 1) uniform texture2D normal_texture; layout(set = 3, binding = 2) uniform texture2D specular_texture; layout(set = 3, binding = 3) uniform sampler texture_sampler; + +layout(set = 3, binding = 4, std430) restrict readonly buffer DrawData { + InstanceData data[]; +} +instances; diff --git a/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl b/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl index 400451ec36..3cbe1427b6 100644 --- a/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl +++ b/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl @@ -156,8 +156,30 @@ vec2 multiview_uv(vec2 uv) { ivec2 multiview_uv(ivec2 uv) { return uv; } + #endif //USE_MULTIVIEW +#if !defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED) && defined(USE_VERTEX_LIGHTING) +layout(location = 12) highp out vec4 diffuse_light_interp; +layout(location = 13) highp out vec4 specular_light_interp; + +#include "../scene_forward_vertex_lights_inc.glsl" + +void cluster_get_item_range(uint p_offset, out uint item_min, out uint item_max, out uint item_from, out uint item_to) { + uint item_min_max = cluster_buffer.data[p_offset]; + item_min = item_min_max & 0xFFFFu; + item_max = item_min_max >> 16; + + item_from = item_min >> 5; + item_to = (item_max == 0) ? 0 : ((item_max - 1) >> 5) + 1; //side effect of how it is stored, as item_max 0 means no elements +} + +uint cluster_get_range_clip_mask(uint i, uint z_min, uint z_max) { + int local_min = clamp(int(z_min) - int(i) * 32, 0, 31); + int mask_width = min(int(z_max) - int(z_min), 32 - local_min); + return bitfieldInsert(uint(0), uint(0xFFFFFFFF), local_min, mask_width); +} +#endif // !defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED) && defined(USE_VERTEX_LIGHTING) invariant gl_Position; #GLOBALS @@ -488,6 +510,145 @@ void vertex_shader(vec3 vertex_input, screen_pos = gl_Position; #endif +#if !defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED) && defined(USE_VERTEX_LIGHTING) + diffuse_light_interp = vec4(0.0); + specular_light_interp = vec4(0.0); + +#ifdef USE_MULTIVIEW + vec3 view = -normalize(vertex_interp - eye_offset); + vec2 clip_pos = clamp((combined_projected.xy / combined_projected.w) * 0.5 + 0.5, 0.0, 1.0); +#else + vec3 view = -normalize(vertex_interp); + vec2 clip_pos = clamp((gl_Position.xy / gl_Position.w) * 0.5 + 0.5, 0.0, 1.0); +#endif + + uvec2 cluster_pos = uvec2(clip_pos / scene_data.screen_pixel_size) >> implementation_data.cluster_shift; + uint cluster_offset = (implementation_data.cluster_width * cluster_pos.y + cluster_pos.x) * (implementation_data.max_cluster_element_count_div_32 + 32); + uint cluster_z = uint(clamp((-vertex_interp.z / scene_data.z_far) * 32.0, 0.0, 31.0)); + + { //omni lights + + uint cluster_omni_offset = cluster_offset; + + uint item_min; + uint item_max; + uint item_from; + uint item_to; + + cluster_get_item_range(cluster_omni_offset + implementation_data.max_cluster_element_count_div_32 + cluster_z, item_min, item_max, item_from, item_to); + + for (uint i = item_from; i < item_to; i++) { + uint mask = cluster_buffer.data[cluster_omni_offset + i]; + mask &= cluster_get_range_clip_mask(i, item_min, item_max); + uint merged_mask = mask; + + while (merged_mask != 0) { + uint bit = findMSB(merged_mask); + merged_mask &= ~(1u << bit); + uint light_index = 32 * i + bit; + + if (!bool(omni_lights.data[light_index].mask & instances.data[instance_index].layer_mask)) { + continue; //not masked + } + + if (omni_lights.data[light_index].bake_mode == LIGHT_BAKE_STATIC && bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_LIGHTMAP)) { + continue; // Statically baked light and object uses lightmap, skip + } + + light_process_omni_vertex(light_index, vertex, view, normal, roughness, + diffuse_light_interp.rgb, specular_light_interp.rgb); + } + } + } + + { //spot lights + uint cluster_spot_offset = cluster_offset + implementation_data.cluster_type_size; + + uint item_min; + uint item_max; + uint item_from; + uint item_to; + + cluster_get_item_range(cluster_spot_offset + implementation_data.max_cluster_element_count_div_32 + cluster_z, item_min, item_max, item_from, item_to); + + for (uint i = item_from; i < item_to; i++) { + uint mask = cluster_buffer.data[cluster_spot_offset + i]; + mask &= cluster_get_range_clip_mask(i, item_min, item_max); + uint merged_mask = mask; + + while (merged_mask != 0) { + uint bit = findMSB(merged_mask); + merged_mask &= ~(1u << bit); + + uint light_index = 32 * i + bit; + + if (!bool(spot_lights.data[light_index].mask & instances.data[instance_index].layer_mask)) { + continue; //not masked + } + + if (spot_lights.data[light_index].bake_mode == LIGHT_BAKE_STATIC && bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_LIGHTMAP)) { + continue; // Statically baked light and object uses lightmap, skip + } + + light_process_spot_vertex(light_index, vertex, view, normal, roughness, + diffuse_light_interp.rgb, specular_light_interp.rgb); + } + } + } + + { // Directional light. + + // We process the first directional light separately as it may have shadows. + vec3 directional_diffuse = vec3(0.0); + vec3 directional_specular = vec3(0.0); + + for (uint i = 0; i < scene_data.directional_light_count; i++) { + if (!bool(directional_lights.data[i].mask & instances.data[draw_call.instance_index].layer_mask)) { + continue; // Not masked, skip. + } + + if (directional_lights.data[i].bake_mode == LIGHT_BAKE_STATIC && bool(instances.data[draw_call.instance_index].flags & INSTANCE_FLAGS_USE_LIGHTMAP)) { + continue; // Statically baked light and object uses lightmap, skip. + } + if (i == 0) { + light_compute_vertex(normal, directional_lights.data[0].direction, view, + directional_lights.data[0].color * directional_lights.data[0].energy, + true, roughness, + directional_diffuse, + directional_specular); + } else { + light_compute_vertex(normal, directional_lights.data[i].direction, view, + directional_lights.data[i].color * directional_lights.data[i].energy, + true, roughness, + diffuse_light_interp.rgb, + specular_light_interp.rgb); + } + } + + // Calculate the contribution from the shadowed light so we can scale the shadows accordingly. + float diff_avg = dot(diffuse_light_interp.rgb, vec3(0.33333)); + float diff_dir_avg = dot(directional_diffuse, vec3(0.33333)); + if (diff_avg > 0.0) { + diffuse_light_interp.a = diff_dir_avg / (diff_avg + diff_dir_avg); + } else { + diffuse_light_interp.a = 1.0; + } + + diffuse_light_interp.rgb += directional_diffuse; + + float spec_avg = dot(specular_light_interp.rgb, vec3(0.33333)); + float spec_dir_avg = dot(directional_specular, vec3(0.33333)); + if (spec_avg > 0.0) { + specular_light_interp.a = spec_dir_avg / (spec_avg + spec_dir_avg); + } else { + specular_light_interp.a = 1.0; + } + + specular_light_interp.rgb += directional_specular; + } + +#endif //!defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED) && defined(USE_VERTEX_LIGHTING) + #ifdef MODE_RENDER_DEPTH if (scene_data.pancake_shadows) { if (gl_Position.z >= 0.9999) { @@ -791,7 +952,10 @@ ivec2 multiview_uv(ivec2 uv) { return uv; } #endif //USE_MULTIVIEW - +#if !defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED) && defined(USE_VERTEX_LIGHTING) +layout(location = 12) highp in vec4 diffuse_light_interp; +layout(location = 13) highp in vec4 specular_light_interp; +#endif //defines to keep compatibility with vertex #ifdef USE_MULTIVIEW @@ -1375,7 +1539,6 @@ void fragment_shader(in SceneData scene_data) { vec3 specular_light = vec3(0.0, 0.0, 0.0); vec3 diffuse_light = vec3(0.0, 0.0, 0.0); vec3 ambient_light = vec3(0.0, 0.0, 0.0); - #ifndef MODE_UNSHADED // Used in regular draw pass and when drawing SDFs for SDFGI and materials for VoxelGI. emission *= scene_data.emissive_exposure_normalization; @@ -1836,6 +1999,11 @@ void fragment_shader(in SceneData scene_data) { // LIGHTING #if !defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED) +#ifdef USE_VERTEX_LIGHTING + diffuse_light += diffuse_light_interp.rgb; + specular_light += specular_light_interp.rgb * f0; +#endif + { // Directional light. // Do shadow and lighting in two passes to reduce register pressure. @@ -1843,10 +2011,15 @@ void fragment_shader(in SceneData scene_data) { uint shadow0 = 0; uint shadow1 = 0; +#ifdef USE_VERTEX_LIGHTING + // Only process the first light's shadow for vertex lighting. + for (uint i = 0; i < 1; i++) { +#else for (uint i = 0; i < 8; i++) { if (i >= scene_data.directional_light_count) { break; } +#endif if (!bool(directional_lights.data[i].mask & instances.data[instance_index].layer_mask)) { continue; //not masked @@ -2044,6 +2217,11 @@ void fragment_shader(in SceneData scene_data) { shadow = mix(shadow, 1.0, smoothstep(directional_lights.data[i].fade_from, directional_lights.data[i].fade_to, vertex.z)); //done with negative values for performance +#ifdef USE_VERTEX_LIGHTING + diffuse_light *= mix(1.0, shadow, diffuse_light_interp.a); + specular_light *= mix(1.0, shadow, specular_light_interp.a); +#endif + #undef BIAS_FUNC } // shadows @@ -2055,6 +2233,8 @@ void fragment_shader(in SceneData scene_data) { } #endif // SHADOWS_DISABLED +#ifndef USE_VERTEX_LIGHTING + for (uint i = 0; i < 8; i++) { if (i >= scene_data.directional_light_count) { break; @@ -2175,8 +2355,10 @@ void fragment_shader(in SceneData scene_data) { diffuse_light, specular_light); } +#endif // USE_VERTEX_LIGHTING } +#ifndef USE_VERTEX_LIGHTING { //omni lights uint cluster_omni_offset = cluster_offset; @@ -2320,6 +2502,8 @@ void fragment_shader(in SceneData scene_data) { } } } +#endif // !USE_VERTEX_LIGHTING +#endif //!defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED) #ifdef USE_SHADOW_TO_OPACITY #ifndef MODE_RENDER_DEPTH @@ -2334,8 +2518,6 @@ void fragment_shader(in SceneData scene_data) { #endif // !MODE_RENDER_DEPTH #endif // USE_SHADOW_TO_OPACITY -#endif //!defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED) - #ifdef MODE_RENDER_DEPTH #ifdef MODE_RENDER_SDF diff --git a/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl b/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl index 17c7b756c3..e7ce44bce2 100644 --- a/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl +++ b/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl @@ -105,7 +105,16 @@ layout(location = 4) mediump out vec2 uv2_interp; layout(location = 5) mediump out vec3 tangent_interp; layout(location = 6) mediump out vec3 binormal_interp; #endif +#if !defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED) && defined(USE_VERTEX_LIGHTING) +layout(location = 7) highp out vec4 diffuse_light_interp; +layout(location = 8) highp out vec4 specular_light_interp; +layout(constant_id = 9) const bool sc_disable_omni_lights = false; +layout(constant_id = 10) const bool sc_disable_spot_lights = false; +layout(constant_id = 12) const bool sc_disable_directional_lights = false; + +#include "../scene_forward_vertex_lights_inc.glsl" +#endif // !defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED) && defined(USE_VERTEX_LIGHTING) #ifdef MATERIAL_UNIFORMS_USED /* clang-format off */ layout(set = MATERIAL_UNIFORM_SET, binding = 0, std140) uniform MaterialUniforms { @@ -185,6 +194,7 @@ void main() { mat4 model_matrix = instances.data[draw_call.instance_index].transform; mat4 inv_view_matrix = scene_data.inv_view_matrix; + #ifdef USE_DOUBLE_PRECISION vec3 model_precision = vec3(model_matrix[0][3], model_matrix[1][3], model_matrix[2][3]); model_matrix[0][3] = 0.0; @@ -448,6 +458,107 @@ void main() { binormal_interp = binormal; #endif +// VERTEX LIGHTING +#if !defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED) && defined(USE_VERTEX_LIGHTING) +#ifdef USE_MULTIVIEW + vec3 view = -normalize(vertex_interp - eye_offset); +#else + vec3 view = -normalize(vertex_interp); +#endif + + diffuse_light_interp = vec4(0.0); + specular_light_interp = vec4(0.0); + + if (!sc_disable_omni_lights) { + uint light_indices = instances.data[draw_call.instance_index].omni_lights.x; + for (uint i = 0; i < 8; i++) { + uint light_index = light_indices & 0xFF; + if (i == 3) { + light_indices = instances.data[draw_call.instance_index].omni_lights.y; + } else { + light_indices = light_indices >> 8; + } + + if (light_index == 0xFF) { + break; + } + + light_process_omni_vertex(light_index, vertex, view, normal, roughness, + diffuse_light_interp.rgb, specular_light_interp.rgb); + } + } + + if (!sc_disable_spot_lights) { + uint light_indices = instances.data[draw_call.instance_index].spot_lights.x; + for (uint i = 0; i < 8; i++) { + uint light_index = light_indices & 0xFF; + if (i == 3) { + light_indices = instances.data[draw_call.instance_index].spot_lights.y; + } else { + light_indices = light_indices >> 8; + } + + if (light_index == 0xFF) { + break; + } + + light_process_spot_vertex(light_index, vertex, view, normal, roughness, + diffuse_light_interp.rgb, specular_light_interp.rgb); + } + } + + if (!sc_disable_directional_lights) { + // We process the first directional light separately as it may have shadows. + vec3 directional_diffuse = vec3(0.0); + vec3 directional_specular = vec3(0.0); + + for (uint i = 0; i < scene_data.directional_light_count; i++) { + if (!bool(directional_lights.data[i].mask & instances.data[draw_call.instance_index].layer_mask)) { + continue; // Not masked, skip. + } + + if (directional_lights.data[i].bake_mode == LIGHT_BAKE_STATIC && bool(instances.data[draw_call.instance_index].flags & INSTANCE_FLAGS_USE_LIGHTMAP)) { + continue; // Statically baked light and object uses lightmap, skip. + } + if (i == 0) { + light_compute_vertex(normal, directional_lights.data[0].direction, view, + directional_lights.data[0].color * directional_lights.data[0].energy, + true, roughness, + directional_diffuse, + directional_specular); + } else { + light_compute_vertex(normal, directional_lights.data[i].direction, view, + directional_lights.data[i].color * directional_lights.data[i].energy, + true, roughness, + diffuse_light_interp.rgb, + specular_light_interp.rgb); + } + } + + // Calculate the contribution from the shadowed light so we can scale the shadows accordingly. + float diff_avg = dot(diffuse_light_interp.rgb, vec3(0.33333)); + float diff_dir_avg = dot(directional_diffuse, vec3(0.33333)); + if (diff_avg > 0.0) { + diffuse_light_interp.a = diff_dir_avg / (diff_avg + diff_dir_avg); + } else { + diffuse_light_interp.a = 1.0; + } + + diffuse_light_interp.rgb += directional_diffuse; + + float spec_avg = dot(specular_light_interp.rgb, vec3(0.33333)); + float spec_dir_avg = dot(directional_specular, vec3(0.33333)); + if (spec_avg > 0.0) { + specular_light_interp.a = spec_dir_avg / (spec_avg + spec_dir_avg); + } else { + specular_light_interp.a = 1.0; + } + + specular_light_interp.rgb += directional_specular; + } + +#endif //!defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED) && defined(USE_VERTEX_LIGHTING) + #ifdef MODE_RENDER_DEPTH #ifdef MODE_DUAL_PARABOLOID @@ -564,6 +675,11 @@ layout(location = 5) mediump in vec3 tangent_interp; layout(location = 6) mediump in vec3 binormal_interp; #endif +#if !defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED) && defined(USE_VERTEX_LIGHTING) +layout(location = 7) highp in vec4 diffuse_light_interp; +layout(location = 8) highp in vec4 specular_light_interp; +#endif + #ifdef MODE_DUAL_PARABOLOID layout(location = 9) highp in float dp_clip; @@ -709,7 +825,7 @@ layout(location = 0) out mediump vec4 frag_color; #include "../scene_forward_aa_inc.glsl" -#if !defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED) +#if !defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED) // && !defined(USE_VERTEX_LIGHTING) // Default to SPECULAR_SCHLICK_GGX. #if !defined(SPECULAR_DISABLED) && !defined(SPECULAR_SCHLICK_GGX) && !defined(SPECULAR_TOON) @@ -718,7 +834,7 @@ layout(location = 0) out mediump vec4 frag_color; #include "../scene_forward_lights_inc.glsl" -#endif //!defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED) +#endif //!defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED) && !defined(USE_VERTEX_LIGHTING) #ifndef MODE_RENDER_DEPTH @@ -1401,6 +1517,10 @@ void main() { // LIGHTING #if !defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED) +#ifdef USE_VERTEX_LIGHTING + diffuse_light += diffuse_light_interp.rgb; + specular_light += specular_light_interp.rgb * f0; +#endif if (!sc_disable_directional_lights) { //directional light #ifndef SHADOWS_DISABLED @@ -1408,10 +1528,12 @@ void main() { uint shadow0 = 0; uint shadow1 = 0; - for (uint i = 0; i < 8; i++) { - if (i >= scene_data.directional_light_count) { - break; - } +#ifdef USE_VERTEX_LIGHTING + // Only process the first light's shadow for vertex lighting. + for (uint i = 0; i < 1; i++) { +#else + for (uint i = 0; i < scene_data.directional_light_count; i++) { +#endif if (!bool(directional_lights.data[i].mask & instances.data[draw_call.instance_index].layer_mask)) { continue; //not masked @@ -1419,164 +1541,6 @@ void main() { float shadow = 1.0; - // Directional light shadow code is basically the same as forward clustered at this point in time minus `LIGHT_TRANSMITTANCE_USED` support. - // Not sure if there is a reason to change this seeing directional lights are part of our global data - // Should think about whether we may want to move this code into an include file or function?? - -#ifdef USE_SOFT_SHADOWS - //version with soft shadows, more expensive - if (directional_lights.data[i].shadow_opacity > 0.001) { - float depth_z = -vertex.z; - - vec4 pssm_coord; - vec3 light_dir = directional_lights.data[i].direction; - -#define BIAS_FUNC(m_var, m_idx) \ - m_var.xyz += light_dir * directional_lights.data[i].shadow_bias[m_idx]; \ - vec3 normal_bias = normalize(normal_interp) * (1.0 - max(0.0, dot(light_dir, -normalize(normal_interp)))) * directional_lights.data[i].shadow_normal_bias[m_idx]; \ - normal_bias -= light_dir * dot(light_dir, normal_bias); \ - m_var.xyz += normal_bias; - - if (depth_z < directional_lights.data[i].shadow_split_offsets.x) { - vec4 v = vec4(vertex, 1.0); - - BIAS_FUNC(v, 0) - - pssm_coord = (directional_lights.data[i].shadow_matrix1 * v); - pssm_coord /= pssm_coord.w; - - if (directional_lights.data[i].softshadow_angle > 0) { - float range_pos = dot(directional_lights.data[i].direction, v.xyz); - float range_begin = directional_lights.data[i].shadow_range_begin.x; - float test_radius = (range_pos - range_begin) * directional_lights.data[i].softshadow_angle; - vec2 tex_scale = directional_lights.data[i].uv_scale1 * test_radius; - shadow = sample_directional_soft_shadow(directional_shadow_atlas, pssm_coord.xyz, tex_scale * directional_lights.data[i].soft_shadow_scale, scene_data.taa_frame_count); - } else { - shadow = sample_directional_pcf_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size * directional_lights.data[i].soft_shadow_scale, pssm_coord, scene_data.taa_frame_count); - } - } else if (depth_z < directional_lights.data[i].shadow_split_offsets.y) { - vec4 v = vec4(vertex, 1.0); - - BIAS_FUNC(v, 1) - - pssm_coord = (directional_lights.data[i].shadow_matrix2 * v); - pssm_coord /= pssm_coord.w; - - if (directional_lights.data[i].softshadow_angle > 0) { - float range_pos = dot(directional_lights.data[i].direction, v.xyz); - float range_begin = directional_lights.data[i].shadow_range_begin.y; - float test_radius = (range_pos - range_begin) * directional_lights.data[i].softshadow_angle; - vec2 tex_scale = directional_lights.data[i].uv_scale2 * test_radius; - shadow = sample_directional_soft_shadow(directional_shadow_atlas, pssm_coord.xyz, tex_scale * directional_lights.data[i].soft_shadow_scale, scene_data.taa_frame_count); - } else { - shadow = sample_directional_pcf_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size * directional_lights.data[i].soft_shadow_scale, pssm_coord, scene_data.taa_frame_count); - } - } else if (depth_z < directional_lights.data[i].shadow_split_offsets.z) { - vec4 v = vec4(vertex, 1.0); - - BIAS_FUNC(v, 2) - - pssm_coord = (directional_lights.data[i].shadow_matrix3 * v); - pssm_coord /= pssm_coord.w; - - if (directional_lights.data[i].softshadow_angle > 0) { - float range_pos = dot(directional_lights.data[i].direction, v.xyz); - float range_begin = directional_lights.data[i].shadow_range_begin.z; - float test_radius = (range_pos - range_begin) * directional_lights.data[i].softshadow_angle; - vec2 tex_scale = directional_lights.data[i].uv_scale3 * test_radius; - shadow = sample_directional_soft_shadow(directional_shadow_atlas, pssm_coord.xyz, tex_scale * directional_lights.data[i].soft_shadow_scale, scene_data.taa_frame_count); - } else { - shadow = sample_directional_pcf_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size * directional_lights.data[i].soft_shadow_scale, pssm_coord, scene_data.taa_frame_count); - } - } else { - vec4 v = vec4(vertex, 1.0); - - BIAS_FUNC(v, 3) - - pssm_coord = (directional_lights.data[i].shadow_matrix4 * v); - pssm_coord /= pssm_coord.w; - - if (directional_lights.data[i].softshadow_angle > 0) { - float range_pos = dot(directional_lights.data[i].direction, v.xyz); - float range_begin = directional_lights.data[i].shadow_range_begin.w; - float test_radius = (range_pos - range_begin) * directional_lights.data[i].softshadow_angle; - vec2 tex_scale = directional_lights.data[i].uv_scale4 * test_radius; - shadow = sample_directional_soft_shadow(directional_shadow_atlas, pssm_coord.xyz, tex_scale * directional_lights.data[i].soft_shadow_scale, scene_data.taa_frame_count); - } else { - shadow = sample_directional_pcf_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size * directional_lights.data[i].soft_shadow_scale, pssm_coord, scene_data.taa_frame_count); - } - } - - if (directional_lights.data[i].blend_splits) { - float pssm_blend; - float shadow2; - - if (depth_z < directional_lights.data[i].shadow_split_offsets.x) { - vec4 v = vec4(vertex, 1.0); - BIAS_FUNC(v, 1) - pssm_coord = (directional_lights.data[i].shadow_matrix2 * v); - pssm_coord /= pssm_coord.w; - - if (directional_lights.data[i].softshadow_angle > 0) { - float range_pos = dot(directional_lights.data[i].direction, v.xyz); - float range_begin = directional_lights.data[i].shadow_range_begin.y; - float test_radius = (range_pos - range_begin) * directional_lights.data[i].softshadow_angle; - vec2 tex_scale = directional_lights.data[i].uv_scale2 * test_radius; - shadow2 = sample_directional_soft_shadow(directional_shadow_atlas, pssm_coord.xyz, tex_scale * directional_lights.data[i].soft_shadow_scale, scene_data.taa_frame_count); - } else { - shadow2 = sample_directional_pcf_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size * directional_lights.data[i].soft_shadow_scale, pssm_coord, scene_data.taa_frame_count); - } - - pssm_blend = smoothstep(0.0, directional_lights.data[i].shadow_split_offsets.x, depth_z); - } else if (depth_z < directional_lights.data[i].shadow_split_offsets.y) { - vec4 v = vec4(vertex, 1.0); - BIAS_FUNC(v, 2) - pssm_coord = (directional_lights.data[i].shadow_matrix3 * v); - pssm_coord /= pssm_coord.w; - - if (directional_lights.data[i].softshadow_angle > 0) { - float range_pos = dot(directional_lights.data[i].direction, v.xyz); - float range_begin = directional_lights.data[i].shadow_range_begin.z; - float test_radius = (range_pos - range_begin) * directional_lights.data[i].softshadow_angle; - vec2 tex_scale = directional_lights.data[i].uv_scale3 * test_radius; - shadow2 = sample_directional_soft_shadow(directional_shadow_atlas, pssm_coord.xyz, tex_scale * directional_lights.data[i].soft_shadow_scale, scene_data.taa_frame_count); - } else { - shadow2 = sample_directional_pcf_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size * directional_lights.data[i].soft_shadow_scale, pssm_coord, scene_data.taa_frame_count); - } - - pssm_blend = smoothstep(directional_lights.data[i].shadow_split_offsets.x, directional_lights.data[i].shadow_split_offsets.y, depth_z); - } else if (depth_z < directional_lights.data[i].shadow_split_offsets.z) { - vec4 v = vec4(vertex, 1.0); - BIAS_FUNC(v, 3) - pssm_coord = (directional_lights.data[i].shadow_matrix4 * v); - pssm_coord /= pssm_coord.w; - if (directional_lights.data[i].softshadow_angle > 0) { - float range_pos = dot(directional_lights.data[i].direction, v.xyz); - float range_begin = directional_lights.data[i].shadow_range_begin.w; - float test_radius = (range_pos - range_begin) * directional_lights.data[i].softshadow_angle; - vec2 tex_scale = directional_lights.data[i].uv_scale4 * test_radius; - shadow2 = sample_directional_soft_shadow(directional_shadow_atlas, pssm_coord.xyz, tex_scale * directional_lights.data[i].soft_shadow_scale, scene_data.taa_frame_count); - } else { - shadow2 = sample_directional_pcf_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size * directional_lights.data[i].soft_shadow_scale, pssm_coord, scene_data.taa_frame_count); - } - - pssm_blend = smoothstep(directional_lights.data[i].shadow_split_offsets.y, directional_lights.data[i].shadow_split_offsets.z, depth_z); - } else { - pssm_blend = 0.0; //if no blend, same coord will be used (divide by z will result in same value, and already cached) - } - - pssm_blend = sqrt(pssm_blend); - - shadow = mix(shadow, shadow2, pssm_blend); - } - - shadow = mix(shadow, 1.0, smoothstep(directional_lights.data[i].fade_from, directional_lights.data[i].fade_to, vertex.z)); //done with negative values for performance - -#undef BIAS_FUNC - } -#else - // Soft shadow disabled version - if (directional_lights.data[i].shadow_opacity > 0.001) { float depth_z = -vertex.z; @@ -1667,6 +1631,10 @@ void main() { shadow = mix(shadow, 1.0, smoothstep(directional_lights.data[i].fade_from, directional_lights.data[i].fade_to, vertex.z)); //done with negative values for performance +#ifdef USE_VERTEX_LIGHTING + diffuse_light *= mix(1.0, shadow, diffuse_light_interp.a); + specular_light *= mix(1.0, shadow, specular_light_interp.a); +#endif #undef BIAS_FUNC } #endif @@ -1678,13 +1646,8 @@ void main() { } } -#endif // SHADOWS_DISABLED - - for (uint i = 0; i < 8; i++) { - if (i >= scene_data.directional_light_count) { - break; - } - +#ifndef USE_VERTEX_LIGHTING + for (uint i = 0; i < scene_data.directional_light_count; i++) { if (!bool(directional_lights.data[i].mask & instances.data[draw_call.instance_index].layer_mask)) { continue; //not masked } @@ -1703,8 +1666,8 @@ void main() { #endif blur_shadow(shadow); -#ifdef DEBUG_DRAW_PSSM_SPLITS vec3 tint = vec3(1.0); +#ifdef DEBUG_DRAW_PSSM_SPLITS if (-vertex.z < directional_lights.data[i].shadow_split_offsets.x) { tint = vec3(1.0, 0.0, 0.0); } else if (-vertex.z < directional_lights.data[i].shadow_split_offsets.y) { @@ -1718,12 +1681,10 @@ void main() { shadow = 1.0; #endif - light_compute(normal, directional_lights.data[i].direction, normalize(view), 0.0, -#ifndef DEBUG_DRAW_PSSM_SPLITS - directional_lights.data[i].color * directional_lights.data[i].energy, -#else + float size_A = sc_use_light_soft_shadows ? directional_lights.data[i].size : 0.0; + + light_compute(normal, directional_lights.data[i].direction, view, size_A, directional_lights.data[i].color * directional_lights.data[i].energy * tint, -#endif true, shadow, f0, orms, 1.0, albedo, alpha, #ifdef LIGHT_BACKLIGHT_USED backlight, @@ -1745,14 +1706,13 @@ void main() { #ifdef LIGHT_ANISOTROPY_USED binormal, tangent, anisotropy, #endif -#ifdef USE_SOFT_SHADOW - directional_lights.data[i].size, -#endif diffuse_light, specular_light); } +#endif // USE_VERTEX_LIGHTING } //directional light +#ifndef USE_VERTEX_LIGHTING if (!sc_disable_omni_lights) { //omni lights uint light_indices = instances.data[draw_call.instance_index].omni_lights.x; for (uint i = 0; i < 8; i++) { @@ -1771,6 +1731,7 @@ void main() { shadow = blur_shadow(shadow); + // Fragment lighting light_process_omni(light_index, vertex, view, normal, vertex_ddx, vertex_ddy, f0, orms, shadow, albedo, alpha, #ifdef LIGHT_BACKLIGHT_USED backlight, @@ -1841,6 +1802,9 @@ void main() { diffuse_light, specular_light); } } //spot lights +#endif // !VERTEX_LIGHTING + +#endif //!defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED) #ifdef USE_SHADOW_TO_OPACITY #ifndef MODE_RENDER_DEPTH @@ -1855,8 +1819,6 @@ void main() { #endif // !MODE_RENDER_DEPTH #endif // USE_SHADOW_TO_OPACITY -#endif //!defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED) - #ifdef MODE_RENDER_DEPTH #ifdef MODE_RENDER_MATERIAL diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_vertex_lights_inc.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_vertex_lights_inc.glsl new file mode 100644 index 0000000000..e962c8f7f3 --- /dev/null +++ b/servers/rendering/renderer_rd/shaders/scene_forward_vertex_lights_inc.glsl @@ -0,0 +1,82 @@ +// Simplified versions of light functions intended for the vertex shader. + +// Eyeballed approximation of `exp2(15.0 * (1.0 - roughness) + 1.0) * 0.25`. +// Uses slightly more FMA instructions (2x rate) to avoid special instructions (0.25x rate). +// Range is reduced to [0.64,4977] from [068,2,221,528] which makes mediump feasible for the rest of the shader. +mediump float roughness_to_shininess(mediump float roughness) { + mediump float r = 1.2 - roughness; + mediump float r2 = r * r; + return r * r2 * r2 * 2000.0; +} + +void light_compute_vertex(vec3 N, vec3 L, vec3 V, vec3 light_color, bool is_directional, float roughness, + inout vec3 diffuse_light, inout vec3 specular_light) { + float NdotL = min(dot(N, L), 1.0); + float cNdotL = max(NdotL, 0.0); // clamped NdotL + +#if defined(DIFFUSE_LAMBERT_WRAP) + // Energy conserving lambert wrap shader. + // https://web.archive.org/web/20210228210901/http://blog.stevemcauley.com/2011/12/03/energy-conserving-wrapped-diffuse/ + float diffuse_brdf_NL = max(0.0, (cNdotL + roughness) / ((1.0 + roughness) * (1.0 + roughness))) * (1.0 / M_PI); +#else + // lambert + float diffuse_brdf_NL = cNdotL * (1.0 / M_PI); +#endif + + diffuse_light += light_color * diffuse_brdf_NL; + +#if !defined(SPECULAR_DISABLED) + float specular_brdf_NL = 0.0; + // Normalized blinn always unless disabled. + vec3 H = normalize(V + L); + float cNdotH = clamp(dot(N, H), 0.0, 1.0); + float shininess = roughness_to_shininess(roughness); + float blinn = pow(cNdotH, shininess); + blinn *= (shininess + 2.0) * (1.0 / (8.0 * M_PI)) * cNdotL; + specular_brdf_NL = blinn; + specular_light += specular_brdf_NL * light_color; +#endif +} + +float get_omni_attenuation(float distance, float inv_range, float decay) { + float nd = distance * inv_range; + nd *= nd; + nd *= nd; // nd^4 + nd = max(1.0 - nd, 0.0); + nd *= nd; // nd^2 + return nd * pow(max(distance, 0.0001), -decay); +} + +void light_process_omni_vertex(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, float roughness, + inout vec3 diffuse_light, inout vec3 specular_light) { + vec3 light_rel_vec = omni_lights.data[idx].position - vertex; + float light_length = length(light_rel_vec); + float omni_attenuation = get_omni_attenuation(light_length, omni_lights.data[idx].inv_radius, omni_lights.data[idx].attenuation); + vec3 color = omni_lights.data[idx].color * omni_attenuation; + + light_compute_vertex(normal, normalize(light_rel_vec), eye_vec, color, false, roughness, + diffuse_light, + specular_light); +} + +void light_process_spot_vertex(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, float roughness, + inout vec3 diffuse_light, + inout vec3 specular_light) { + vec3 light_rel_vec = spot_lights.data[idx].position - vertex; + float light_length = length(light_rel_vec); + float spot_attenuation = get_omni_attenuation(light_length, spot_lights.data[idx].inv_radius, spot_lights.data[idx].attenuation); + vec3 spot_dir = spot_lights.data[idx].direction; + + // This conversion to a highp float is crucial to prevent light leaking + // due to precision errors in the following calculations (cone angle is mediump). + highp float cone_angle = spot_lights.data[idx].cone_angle; + float scos = max(dot(-normalize(light_rel_vec), spot_dir), cone_angle); + float spot_rim = max(0.0001, (1.0 - scos) / (1.0 - cone_angle)); + + spot_attenuation *= 1.0 - pow(spot_rim, spot_lights.data[idx].cone_attenuation); + vec3 color = spot_lights.data[idx].color * spot_attenuation; + float specular_amount = spot_lights.data[idx].specular_amount; + + light_compute_vertex(normal, normalize(light_rel_vec), eye_vec, color, false, roughness, + diffuse_light, specular_light); +} diff --git a/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp b/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp index e5a8dbb9b2..84e8d1d671 100644 --- a/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp +++ b/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp @@ -40,25 +40,12 @@ using namespace RendererRD; /////////////////////////////////////////////////////////////////////////// // TextureStorage::CanvasTexture -void TextureStorage::CanvasTexture::clear_sets() { - if (cleared_cache) { - return; - } - for (int i = 1; i < RS::CANVAS_ITEM_TEXTURE_FILTER_MAX; i++) { - for (int j = 1; j < RS::CANVAS_ITEM_TEXTURE_REPEAT_MAX; j++) { - for (int k = 0; k < 2; k++) { - if (RD::get_singleton()->uniform_set_is_valid(uniform_sets[i][j][k])) { - RD::get_singleton()->free(uniform_sets[i][j][k]); - uniform_sets[i][j][k] = RID(); - } - } - } - } - cleared_cache = true; +void TextureStorage::CanvasTexture::clear_cache() { + info_cache[0] = CanvasTextureCache(); + info_cache[1] = CanvasTextureCache(); } TextureStorage::CanvasTexture::~CanvasTexture() { - clear_sets(); } /////////////////////////////////////////////////////////////////////////// @@ -612,8 +599,7 @@ void TextureStorage::canvas_texture_set_channel(RID p_canvas_texture, RS::Canvas ct->specular = p_texture; } break; } - - ct->clear_sets(); + ct->clear_cache(); } void TextureStorage::canvas_texture_set_shading_parameters(RID p_canvas_texture, const Color &p_specular_color, float p_shininess) { @@ -624,7 +610,6 @@ void TextureStorage::canvas_texture_set_shading_parameters(RID p_canvas_texture, ct->specular_color.g = p_specular_color.g; ct->specular_color.b = p_specular_color.b; ct->specular_color.a = p_shininess; - ct->clear_sets(); } void TextureStorage::canvas_texture_set_texture_filter(RID p_canvas_texture, RS::CanvasItemTextureFilter p_filter) { @@ -632,7 +617,6 @@ void TextureStorage::canvas_texture_set_texture_filter(RID p_canvas_texture, RS: ERR_FAIL_NULL(ct); ct->texture_filter = p_filter; - ct->clear_sets(); } void TextureStorage::canvas_texture_set_texture_repeat(RID p_canvas_texture, RS::CanvasItemTextureRepeat p_repeat) { @@ -640,17 +624,14 @@ void TextureStorage::canvas_texture_set_texture_repeat(RID p_canvas_texture, RS: ERR_FAIL_NULL(ct); ct->texture_repeat = p_repeat; - ct->clear_sets(); } -bool TextureStorage::canvas_texture_get_uniform_set(RID p_texture, RS::CanvasItemTextureFilter p_base_filter, RS::CanvasItemTextureRepeat p_base_repeat, RID p_base_shader, int p_base_set, bool p_use_srgb, RID &r_uniform_set, Size2i &r_size, Color &r_specular_shininess, bool &r_use_normal, bool &r_use_specular, bool p_texture_is_data) { +TextureStorage::CanvasTextureInfo TextureStorage::canvas_texture_get_info(RID p_texture, RS::CanvasItemTextureFilter p_base_filter, RS::CanvasItemTextureRepeat p_base_repeat, bool p_use_srgb, bool p_texture_is_data) { MaterialStorage *material_storage = MaterialStorage::get_singleton(); CanvasTexture *ct = nullptr; Texture *t = get_texture(p_texture); - // TODO once we have our texture storage split off we'll look into moving this code into canvas_texture - if (t) { //regular texture if (!t->canvas_texture) { @@ -667,93 +648,71 @@ bool TextureStorage::canvas_texture_get_uniform_set(RID p_texture, RS::CanvasIte } if (!ct) { - return false; //invalid texture RID + return CanvasTextureInfo(); //invalid texture RID } RS::CanvasItemTextureFilter filter = ct->texture_filter != RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT ? ct->texture_filter : p_base_filter; - ERR_FAIL_COND_V(filter == RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, false); + ERR_FAIL_COND_V(filter == RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, CanvasTextureInfo()); RS::CanvasItemTextureRepeat repeat = ct->texture_repeat != RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT ? ct->texture_repeat : p_base_repeat; - ERR_FAIL_COND_V(repeat == RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT, false); + ERR_FAIL_COND_V(repeat == RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT, CanvasTextureInfo()); - RID uniform_set = ct->uniform_sets[filter][repeat][int(p_use_srgb)]; - if (!RD::get_singleton()->uniform_set_is_valid(uniform_set)) { - //create and update - Vector<RD::Uniform> uniforms; + CanvasTextureCache &ctc = ct->info_cache[int(p_use_srgb)]; + if (!RD::get_singleton()->texture_is_valid(ctc.diffuse) || + !RD::get_singleton()->texture_is_valid(ctc.normal) || + !RD::get_singleton()->texture_is_valid(ctc.specular)) { { //diffuse - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - u.binding = 0; - t = get_texture(ct->diffuse); if (!t) { - u.append_id(texture_rd_get_default(DEFAULT_RD_TEXTURE_WHITE)); + ctc.diffuse = texture_rd_get_default(DEFAULT_RD_TEXTURE_WHITE); ct->size_cache = Size2i(1, 1); } else { - u.append_id(t->rd_texture_srgb.is_valid() && p_use_srgb && !p_texture_is_data ? t->rd_texture_srgb : t->rd_texture); + ctc.diffuse = t->rd_texture_srgb.is_valid() && p_use_srgb && !p_texture_is_data ? t->rd_texture_srgb : t->rd_texture; ct->size_cache = Size2i(t->width_2d, t->height_2d); if (t->render_target) { t->render_target->was_used = true; } } - uniforms.push_back(u); } { //normal - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - u.binding = 1; - t = get_texture(ct->normal_map); if (!t) { - u.append_id(texture_rd_get_default(DEFAULT_RD_TEXTURE_NORMAL)); + ctc.normal = texture_rd_get_default(DEFAULT_RD_TEXTURE_NORMAL); ct->use_normal_cache = false; } else { - u.append_id(t->rd_texture); + ctc.normal = t->rd_texture; ct->use_normal_cache = true; if (t->render_target) { t->render_target->was_used = true; } } - uniforms.push_back(u); } { //specular - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - u.binding = 2; - t = get_texture(ct->specular); if (!t) { - u.append_id(texture_rd_get_default(DEFAULT_RD_TEXTURE_WHITE)); + ctc.specular = texture_rd_get_default(DEFAULT_RD_TEXTURE_WHITE); ct->use_specular_cache = false; } else { - u.append_id(t->rd_texture); + ctc.specular = t->rd_texture; ct->use_specular_cache = true; if (t->render_target) { t->render_target->was_used = true; } } - uniforms.push_back(u); } - { //sampler - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; - u.binding = 3; - u.append_id(material_storage->sampler_rd_get_default(filter, repeat)); - uniforms.push_back(u); - } - - uniform_set = RD::get_singleton()->uniform_set_create(uniforms, p_base_shader, p_base_set); - ct->uniform_sets[filter][repeat][int(p_use_srgb)] = uniform_set; - ct->cleared_cache = false; } - r_uniform_set = uniform_set; - r_size = ct->size_cache; - r_specular_shininess = ct->specular_color; - r_use_normal = ct->use_normal_cache; - r_use_specular = ct->use_specular_cache; + CanvasTextureInfo res; + res.diffuse = ctc.diffuse; + res.normal = ctc.normal; + res.specular = ctc.specular; + res.sampler = material_storage->sampler_rd_get_default(filter, repeat); + res.size = ct->size_cache; + res.specular_color = ct->specular_color; + res.use_normal = ct->use_normal_cache; + res.use_specular = ct->use_specular_cache; - return true; + return res; } /* Texture API */ diff --git a/servers/rendering/renderer_rd/storage_rd/texture_storage.h b/servers/rendering/renderer_rd/storage_rd/texture_storage.h index 9de4ff7b6b..8aecc78f07 100644 --- a/servers/rendering/renderer_rd/storage_rd/texture_storage.h +++ b/servers/rendering/renderer_rd/storage_rd/texture_storage.h @@ -76,6 +76,21 @@ public: TYPE_3D }; + struct CanvasTextureInfo { + RID diffuse; + RID normal; + RID specular; + RID sampler; + Size2i size; + Color specular_color; + + bool use_normal = false; + bool use_specular = false; + + _FORCE_INLINE_ bool is_valid() const { return diffuse.is_valid(); } + _FORCE_INLINE_ bool is_null() const { return diffuse.is_null(); } + }; + private: friend class LightStorage; friend class MaterialStorage; @@ -86,6 +101,12 @@ private: /* Canvas Texture API */ + struct CanvasTextureCache { + RID diffuse = RID(); + RID normal = RID(); + RID specular = RID(); + }; + class CanvasTexture { public: RID diffuse; @@ -96,14 +117,14 @@ private: RS::CanvasItemTextureFilter texture_filter = RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT; RS::CanvasItemTextureRepeat texture_repeat = RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT; - RID uniform_sets[RS::CANVAS_ITEM_TEXTURE_FILTER_MAX][RS::CANVAS_ITEM_TEXTURE_REPEAT_MAX][2]; + CanvasTextureCache info_cache[2]; Size2i size_cache = Size2i(1, 1); bool use_normal_cache = false; bool use_specular_cache = false; bool cleared_cache = true; - void clear_sets(); + void clear_cache(); ~CanvasTexture(); }; @@ -477,7 +498,7 @@ public: virtual void canvas_texture_set_texture_filter(RID p_item, RS::CanvasItemTextureFilter p_filter) override; virtual void canvas_texture_set_texture_repeat(RID p_item, RS::CanvasItemTextureRepeat p_repeat) override; - bool canvas_texture_get_uniform_set(RID p_texture, RS::CanvasItemTextureFilter p_base_filter, RS::CanvasItemTextureRepeat p_base_repeat, RID p_base_shader, int p_base_set, bool p_use_srgb, RID &r_uniform_set, Size2i &r_size, Color &r_specular_shininess, bool &r_use_normal, bool &r_use_specular, bool p_texture_is_data); + CanvasTextureInfo canvas_texture_get_info(RID p_texture, RS::CanvasItemTextureFilter p_base_filter, RS::CanvasItemTextureRepeat p_base_repeat, bool p_use_srgb, bool p_texture_is_data); /* Texture API */ diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp index 0ad56961c0..5c85080298 100644 --- a/servers/rendering_server.cpp +++ b/servers/rendering_server.cpp @@ -3580,8 +3580,7 @@ void RenderingServer::init() { GLOBAL_DEF(PropertyInfo(Variant::INT, "rendering/global_illumination/voxel_gi/quality", PROPERTY_HINT_ENUM, "Low (4 Cones - Fast),High (6 Cones - Slow)"), 0); - GLOBAL_DEF("rendering/shading/overrides/force_vertex_shading", false); - GLOBAL_DEF("rendering/shading/overrides/force_vertex_shading.mobile", true); + GLOBAL_DEF_RST("rendering/shading/overrides/force_vertex_shading", false); GLOBAL_DEF("rendering/shading/overrides/force_lambert_over_burley", false); GLOBAL_DEF("rendering/shading/overrides/force_lambert_over_burley.mobile", true); diff --git a/servers/text/text_server_extension.cpp b/servers/text/text_server_extension.cpp index d387c8ff7e..1c0d518e75 100644 --- a/servers/text/text_server_extension.cpp +++ b/servers/text/text_server_extension.cpp @@ -352,29 +352,29 @@ void TextServerExtension::_bind_methods() { bool TextServerExtension::has_feature(Feature p_feature) const { bool ret = false; - GDVIRTUAL_REQUIRED_CALL(_has_feature, p_feature, ret); + GDVIRTUAL_CALL(_has_feature, p_feature, ret); return ret; } String TextServerExtension::get_name() const { String ret = "Unknown"; - GDVIRTUAL_REQUIRED_CALL(_get_name, ret); + GDVIRTUAL_CALL(_get_name, ret); return ret; } int64_t TextServerExtension::get_features() const { int64_t ret = 0; - GDVIRTUAL_REQUIRED_CALL(_get_features, ret); + GDVIRTUAL_CALL(_get_features, ret); return ret; } void TextServerExtension::free_rid(const RID &p_rid) { - GDVIRTUAL_REQUIRED_CALL(_free_rid, p_rid); + GDVIRTUAL_CALL(_free_rid, p_rid); } bool TextServerExtension::has(const RID &p_rid) { bool ret = false; - GDVIRTUAL_REQUIRED_CALL(_has, p_rid, ret); + GDVIRTUAL_CALL(_has, p_rid, ret); return ret; } @@ -430,7 +430,7 @@ String TextServerExtension::tag_to_name(int64_t p_tag) const { RID TextServerExtension::create_font() { RID ret; - GDVIRTUAL_REQUIRED_CALL(_create_font, ret); + GDVIRTUAL_CALL(_create_font, ret); return ret; } @@ -581,22 +581,22 @@ int64_t TextServerExtension::font_get_msdf_size(const RID &p_font_rid) const { } void TextServerExtension::font_set_fixed_size(const RID &p_font_rid, int64_t p_fixed_size) { - GDVIRTUAL_REQUIRED_CALL(_font_set_fixed_size, p_font_rid, p_fixed_size); + GDVIRTUAL_CALL(_font_set_fixed_size, p_font_rid, p_fixed_size); } int64_t TextServerExtension::font_get_fixed_size(const RID &p_font_rid) const { int64_t ret = 0; - GDVIRTUAL_REQUIRED_CALL(_font_get_fixed_size, p_font_rid, ret); + GDVIRTUAL_CALL(_font_get_fixed_size, p_font_rid, ret); return ret; } void TextServerExtension::font_set_fixed_size_scale_mode(const RID &p_font_rid, TextServer::FixedSizeScaleMode p_fixed_size_scale_mode) { - GDVIRTUAL_REQUIRED_CALL(_font_set_fixed_size_scale_mode, p_font_rid, p_fixed_size_scale_mode); + GDVIRTUAL_CALL(_font_set_fixed_size_scale_mode, p_font_rid, p_fixed_size_scale_mode); } TextServer::FixedSizeScaleMode TextServerExtension::font_get_fixed_size_scale_mode(const RID &p_font_rid) const { FixedSizeScaleMode ret = FIXED_SIZE_SCALE_DISABLE; - GDVIRTUAL_REQUIRED_CALL(_font_get_fixed_size_scale_mode, p_font_rid, ret); + GDVIRTUAL_CALL(_font_get_fixed_size_scale_mode, p_font_rid, ret); return ret; } @@ -702,89 +702,89 @@ double TextServerExtension::font_get_oversampling(const RID &p_font_rid) const { TypedArray<Vector2i> TextServerExtension::font_get_size_cache_list(const RID &p_font_rid) const { TypedArray<Vector2i> ret; - GDVIRTUAL_REQUIRED_CALL(_font_get_size_cache_list, p_font_rid, ret); + GDVIRTUAL_CALL(_font_get_size_cache_list, p_font_rid, ret); return ret; } void TextServerExtension::font_clear_size_cache(const RID &p_font_rid) { - GDVIRTUAL_REQUIRED_CALL(_font_clear_size_cache, p_font_rid); + GDVIRTUAL_CALL(_font_clear_size_cache, p_font_rid); } void TextServerExtension::font_remove_size_cache(const RID &p_font_rid, const Vector2i &p_size) { - GDVIRTUAL_REQUIRED_CALL(_font_remove_size_cache, p_font_rid, p_size); + GDVIRTUAL_CALL(_font_remove_size_cache, p_font_rid, p_size); } void TextServerExtension::font_set_ascent(const RID &p_font_rid, int64_t p_size, double p_ascent) { - GDVIRTUAL_REQUIRED_CALL(_font_set_ascent, p_font_rid, p_size, p_ascent); + GDVIRTUAL_CALL(_font_set_ascent, p_font_rid, p_size, p_ascent); } double TextServerExtension::font_get_ascent(const RID &p_font_rid, int64_t p_size) const { double ret = 0; - GDVIRTUAL_REQUIRED_CALL(_font_get_ascent, p_font_rid, p_size, ret); + GDVIRTUAL_CALL(_font_get_ascent, p_font_rid, p_size, ret); return ret; } void TextServerExtension::font_set_descent(const RID &p_font_rid, int64_t p_size, double p_descent) { - GDVIRTUAL_REQUIRED_CALL(_font_set_descent, p_font_rid, p_size, p_descent); + GDVIRTUAL_CALL(_font_set_descent, p_font_rid, p_size, p_descent); } double TextServerExtension::font_get_descent(const RID &p_font_rid, int64_t p_size) const { double ret = 0; - GDVIRTUAL_REQUIRED_CALL(_font_get_descent, p_font_rid, p_size, ret); + GDVIRTUAL_CALL(_font_get_descent, p_font_rid, p_size, ret); return ret; } void TextServerExtension::font_set_underline_position(const RID &p_font_rid, int64_t p_size, double p_underline_position) { - GDVIRTUAL_REQUIRED_CALL(_font_set_underline_position, p_font_rid, p_size, p_underline_position); + GDVIRTUAL_CALL(_font_set_underline_position, p_font_rid, p_size, p_underline_position); } double TextServerExtension::font_get_underline_position(const RID &p_font_rid, int64_t p_size) const { double ret = 0; - GDVIRTUAL_REQUIRED_CALL(_font_get_underline_position, p_font_rid, p_size, ret); + GDVIRTUAL_CALL(_font_get_underline_position, p_font_rid, p_size, ret); return ret; } void TextServerExtension::font_set_underline_thickness(const RID &p_font_rid, int64_t p_size, double p_underline_thickness) { - GDVIRTUAL_REQUIRED_CALL(_font_set_underline_thickness, p_font_rid, p_size, p_underline_thickness); + GDVIRTUAL_CALL(_font_set_underline_thickness, p_font_rid, p_size, p_underline_thickness); } double TextServerExtension::font_get_underline_thickness(const RID &p_font_rid, int64_t p_size) const { double ret = 0; - GDVIRTUAL_REQUIRED_CALL(_font_get_underline_thickness, p_font_rid, p_size, ret); + GDVIRTUAL_CALL(_font_get_underline_thickness, p_font_rid, p_size, ret); return ret; } void TextServerExtension::font_set_scale(const RID &p_font_rid, int64_t p_size, double p_scale) { - GDVIRTUAL_REQUIRED_CALL(_font_set_scale, p_font_rid, p_size, p_scale); + GDVIRTUAL_CALL(_font_set_scale, p_font_rid, p_size, p_scale); } double TextServerExtension::font_get_scale(const RID &p_font_rid, int64_t p_size) const { double ret = 0; - GDVIRTUAL_REQUIRED_CALL(_font_get_scale, p_font_rid, p_size, ret); + GDVIRTUAL_CALL(_font_get_scale, p_font_rid, p_size, ret); return ret; } int64_t TextServerExtension::font_get_texture_count(const RID &p_font_rid, const Vector2i &p_size) const { int64_t ret = 0; - GDVIRTUAL_REQUIRED_CALL(_font_get_texture_count, p_font_rid, p_size, ret); + GDVIRTUAL_CALL(_font_get_texture_count, p_font_rid, p_size, ret); return ret; } void TextServerExtension::font_clear_textures(const RID &p_font_rid, const Vector2i &p_size) { - GDVIRTUAL_REQUIRED_CALL(_font_clear_textures, p_font_rid, p_size); + GDVIRTUAL_CALL(_font_clear_textures, p_font_rid, p_size); } void TextServerExtension::font_remove_texture(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index) { - GDVIRTUAL_REQUIRED_CALL(_font_remove_texture, p_font_rid, p_size, p_texture_index); + GDVIRTUAL_CALL(_font_remove_texture, p_font_rid, p_size, p_texture_index); } void TextServerExtension::font_set_texture_image(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index, const Ref<Image> &p_image) { - GDVIRTUAL_REQUIRED_CALL(_font_set_texture_image, p_font_rid, p_size, p_texture_index, p_image); + GDVIRTUAL_CALL(_font_set_texture_image, p_font_rid, p_size, p_texture_index, p_image); } Ref<Image> TextServerExtension::font_get_texture_image(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index) const { Ref<Image> ret; - GDVIRTUAL_REQUIRED_CALL(_font_get_texture_image, p_font_rid, p_size, p_texture_index, ret); + GDVIRTUAL_CALL(_font_get_texture_image, p_font_rid, p_size, p_texture_index, ret); return ret; } @@ -800,77 +800,77 @@ PackedInt32Array TextServerExtension::font_get_texture_offsets(const RID &p_font PackedInt32Array TextServerExtension::font_get_glyph_list(const RID &p_font_rid, const Vector2i &p_size) const { PackedInt32Array ret; - GDVIRTUAL_REQUIRED_CALL(_font_get_glyph_list, p_font_rid, p_size, ret); + GDVIRTUAL_CALL(_font_get_glyph_list, p_font_rid, p_size, ret); return ret; } void TextServerExtension::font_clear_glyphs(const RID &p_font_rid, const Vector2i &p_size) { - GDVIRTUAL_REQUIRED_CALL(_font_clear_glyphs, p_font_rid, p_size); + GDVIRTUAL_CALL(_font_clear_glyphs, p_font_rid, p_size); } void TextServerExtension::font_remove_glyph(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) { - GDVIRTUAL_REQUIRED_CALL(_font_remove_glyph, p_font_rid, p_size, p_glyph); + GDVIRTUAL_CALL(_font_remove_glyph, p_font_rid, p_size, p_glyph); } Vector2 TextServerExtension::font_get_glyph_advance(const RID &p_font_rid, int64_t p_size, int64_t p_glyph) const { Vector2 ret; - GDVIRTUAL_REQUIRED_CALL(_font_get_glyph_advance, p_font_rid, p_size, p_glyph, ret); + GDVIRTUAL_CALL(_font_get_glyph_advance, p_font_rid, p_size, p_glyph, ret); return ret; } void TextServerExtension::font_set_glyph_advance(const RID &p_font_rid, int64_t p_size, int64_t p_glyph, const Vector2 &p_advance) { - GDVIRTUAL_REQUIRED_CALL(_font_set_glyph_advance, p_font_rid, p_size, p_glyph, p_advance); + GDVIRTUAL_CALL(_font_set_glyph_advance, p_font_rid, p_size, p_glyph, p_advance); } Vector2 TextServerExtension::font_get_glyph_offset(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const { Vector2 ret; - GDVIRTUAL_REQUIRED_CALL(_font_get_glyph_offset, p_font_rid, p_size, p_glyph, ret); + GDVIRTUAL_CALL(_font_get_glyph_offset, p_font_rid, p_size, p_glyph, ret); return ret; } void TextServerExtension::font_set_glyph_offset(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph, const Vector2 &p_offset) { - GDVIRTUAL_REQUIRED_CALL(_font_set_glyph_offset, p_font_rid, p_size, p_glyph, p_offset); + GDVIRTUAL_CALL(_font_set_glyph_offset, p_font_rid, p_size, p_glyph, p_offset); } Vector2 TextServerExtension::font_get_glyph_size(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const { Vector2 ret; - GDVIRTUAL_REQUIRED_CALL(_font_get_glyph_size, p_font_rid, p_size, p_glyph, ret); + GDVIRTUAL_CALL(_font_get_glyph_size, p_font_rid, p_size, p_glyph, ret); return ret; } void TextServerExtension::font_set_glyph_size(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph, const Vector2 &p_gl_size) { - GDVIRTUAL_REQUIRED_CALL(_font_set_glyph_size, p_font_rid, p_size, p_glyph, p_gl_size); + GDVIRTUAL_CALL(_font_set_glyph_size, p_font_rid, p_size, p_glyph, p_gl_size); } Rect2 TextServerExtension::font_get_glyph_uv_rect(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const { Rect2 ret; - GDVIRTUAL_REQUIRED_CALL(_font_get_glyph_uv_rect, p_font_rid, p_size, p_glyph, ret); + GDVIRTUAL_CALL(_font_get_glyph_uv_rect, p_font_rid, p_size, p_glyph, ret); return ret; } void TextServerExtension::font_set_glyph_uv_rect(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph, const Rect2 &p_uv_rect) { - GDVIRTUAL_REQUIRED_CALL(_font_set_glyph_uv_rect, p_font_rid, p_size, p_glyph, p_uv_rect); + GDVIRTUAL_CALL(_font_set_glyph_uv_rect, p_font_rid, p_size, p_glyph, p_uv_rect); } int64_t TextServerExtension::font_get_glyph_texture_idx(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const { int64_t ret = 0; - GDVIRTUAL_REQUIRED_CALL(_font_get_glyph_texture_idx, p_font_rid, p_size, p_glyph, ret); + GDVIRTUAL_CALL(_font_get_glyph_texture_idx, p_font_rid, p_size, p_glyph, ret); return ret; } void TextServerExtension::font_set_glyph_texture_idx(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph, int64_t p_texture_idx) { - GDVIRTUAL_REQUIRED_CALL(_font_set_glyph_texture_idx, p_font_rid, p_size, p_glyph, p_texture_idx); + GDVIRTUAL_CALL(_font_set_glyph_texture_idx, p_font_rid, p_size, p_glyph, p_texture_idx); } RID TextServerExtension::font_get_glyph_texture_rid(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const { RID ret; - GDVIRTUAL_REQUIRED_CALL(_font_get_glyph_texture_rid, p_font_rid, p_size, p_glyph, ret); + GDVIRTUAL_CALL(_font_get_glyph_texture_rid, p_font_rid, p_size, p_glyph, ret); return ret; } Size2 TextServerExtension::font_get_glyph_texture_size(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const { Size2 ret; - GDVIRTUAL_REQUIRED_CALL(_font_get_glyph_texture_size, p_font_rid, p_size, p_glyph, ret); + GDVIRTUAL_CALL(_font_get_glyph_texture_size, p_font_rid, p_size, p_glyph, ret); return ret; } @@ -906,31 +906,31 @@ Vector2 TextServerExtension::font_get_kerning(const RID &p_font_rid, int64_t p_s int64_t TextServerExtension::font_get_glyph_index(const RID &p_font_rid, int64_t p_size, int64_t p_char, int64_t p_variation_selector) const { int64_t ret = 0; - GDVIRTUAL_REQUIRED_CALL(_font_get_glyph_index, p_font_rid, p_size, p_char, p_variation_selector, ret); + GDVIRTUAL_CALL(_font_get_glyph_index, p_font_rid, p_size, p_char, p_variation_selector, ret); return ret; } int64_t TextServerExtension::font_get_char_from_glyph_index(const RID &p_font_rid, int64_t p_size, int64_t p_glyph_index) const { int64_t ret = 0; - GDVIRTUAL_REQUIRED_CALL(_font_get_char_from_glyph_index, p_font_rid, p_size, p_glyph_index, ret); + GDVIRTUAL_CALL(_font_get_char_from_glyph_index, p_font_rid, p_size, p_glyph_index, ret); return ret; } bool TextServerExtension::font_has_char(const RID &p_font_rid, int64_t p_char) const { bool ret = false; - GDVIRTUAL_REQUIRED_CALL(_font_has_char, p_font_rid, p_char, ret); + GDVIRTUAL_CALL(_font_has_char, p_font_rid, p_char, ret); return ret; } String TextServerExtension::font_get_supported_chars(const RID &p_font_rid) const { String ret; - GDVIRTUAL_REQUIRED_CALL(_font_get_supported_chars, p_font_rid, ret); + GDVIRTUAL_CALL(_font_get_supported_chars, p_font_rid, ret); return ret; } PackedInt32Array TextServerExtension::font_get_supported_glyphs(const RID &p_font_rid) const { PackedInt32Array ret; - GDVIRTUAL_REQUIRED_CALL(_font_get_supported_glyphs, p_font_rid, ret); + GDVIRTUAL_CALL(_font_get_supported_glyphs, p_font_rid, ret); return ret; } @@ -943,11 +943,11 @@ void TextServerExtension::font_render_glyph(const RID &p_font_rid, const Vector2 } void TextServerExtension::font_draw_glyph(const RID &p_font_rid, const RID &p_canvas, int64_t p_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color) const { - GDVIRTUAL_REQUIRED_CALL(_font_draw_glyph, p_font_rid, p_canvas, p_size, p_pos, p_index, p_color); + GDVIRTUAL_CALL(_font_draw_glyph, p_font_rid, p_canvas, p_size, p_pos, p_index, p_color); } void TextServerExtension::font_draw_glyph_outline(const RID &p_font_rid, const RID &p_canvas, int64_t p_size, int64_t p_outline_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color) const { - GDVIRTUAL_REQUIRED_CALL(_font_draw_glyph_outline, p_font_rid, p_canvas, p_size, p_outline_size, p_pos, p_index, p_color); + GDVIRTUAL_CALL(_font_draw_glyph_outline, p_font_rid, p_canvas, p_size, p_outline_size, p_pos, p_index, p_color); } bool TextServerExtension::font_is_language_supported(const RID &p_font_rid, const String &p_language) const { @@ -1054,12 +1054,12 @@ void TextServerExtension::draw_hex_code_box(const RID &p_canvas, int64_t p_size, RID TextServerExtension::create_shaped_text(TextServer::Direction p_direction, TextServer::Orientation p_orientation) { RID ret; - GDVIRTUAL_REQUIRED_CALL(_create_shaped_text, p_direction, p_orientation, ret); + GDVIRTUAL_CALL(_create_shaped_text, p_direction, p_orientation, ret); return ret; } void TextServerExtension::shaped_text_clear(const RID &p_shaped) { - GDVIRTUAL_REQUIRED_CALL(_shaped_text_clear, p_shaped); + GDVIRTUAL_CALL(_shaped_text_clear, p_shaped); } void TextServerExtension::shaped_text_set_direction(const RID &p_shaped, TextServer::Direction p_direction) { @@ -1144,47 +1144,47 @@ int64_t TextServerExtension::shaped_text_get_spacing(const RID &p_shaped, TextSe bool TextServerExtension::shaped_text_add_string(const RID &p_shaped, const String &p_text, const TypedArray<RID> &p_fonts, int64_t p_size, const Dictionary &p_opentype_features, const String &p_language, const Variant &p_meta) { bool ret = false; - GDVIRTUAL_REQUIRED_CALL(_shaped_text_add_string, p_shaped, p_text, p_fonts, p_size, p_opentype_features, p_language, p_meta, ret); + GDVIRTUAL_CALL(_shaped_text_add_string, p_shaped, p_text, p_fonts, p_size, p_opentype_features, p_language, p_meta, ret); return ret; } bool TextServerExtension::shaped_text_add_object(const RID &p_shaped, const Variant &p_key, const Size2 &p_size, InlineAlignment p_inline_align, int64_t p_length, double p_baseline) { bool ret = false; - GDVIRTUAL_REQUIRED_CALL(_shaped_text_add_object, p_shaped, p_key, p_size, p_inline_align, p_length, p_baseline, ret); + GDVIRTUAL_CALL(_shaped_text_add_object, p_shaped, p_key, p_size, p_inline_align, p_length, p_baseline, ret); return ret; } bool TextServerExtension::shaped_text_resize_object(const RID &p_shaped, const Variant &p_key, const Size2 &p_size, InlineAlignment p_inline_align, double p_baseline) { bool ret = false; - GDVIRTUAL_REQUIRED_CALL(_shaped_text_resize_object, p_shaped, p_key, p_size, p_inline_align, p_baseline, ret); + GDVIRTUAL_CALL(_shaped_text_resize_object, p_shaped, p_key, p_size, p_inline_align, p_baseline, ret); return ret; } int64_t TextServerExtension::shaped_get_span_count(const RID &p_shaped) const { int64_t ret = 0; - GDVIRTUAL_REQUIRED_CALL(_shaped_get_span_count, p_shaped, ret); + GDVIRTUAL_CALL(_shaped_get_span_count, p_shaped, ret); return ret; } Variant TextServerExtension::shaped_get_span_meta(const RID &p_shaped, int64_t p_index) const { Variant ret = false; - GDVIRTUAL_REQUIRED_CALL(_shaped_get_span_meta, p_shaped, p_index, ret); + GDVIRTUAL_CALL(_shaped_get_span_meta, p_shaped, p_index, ret); return ret; } void TextServerExtension::shaped_set_span_update_font(const RID &p_shaped, int64_t p_index, const TypedArray<RID> &p_fonts, int64_t p_size, const Dictionary &p_opentype_features) { - GDVIRTUAL_REQUIRED_CALL(_shaped_set_span_update_font, p_shaped, p_index, p_fonts, p_size, p_opentype_features); + GDVIRTUAL_CALL(_shaped_set_span_update_font, p_shaped, p_index, p_fonts, p_size, p_opentype_features); } RID TextServerExtension::shaped_text_substr(const RID &p_shaped, int64_t p_start, int64_t p_length) const { RID ret; - GDVIRTUAL_REQUIRED_CALL(_shaped_text_substr, p_shaped, p_start, p_length, ret); + GDVIRTUAL_CALL(_shaped_text_substr, p_shaped, p_start, p_length, ret); return ret; } RID TextServerExtension::shaped_text_get_parent(const RID &p_shaped) const { RID ret; - GDVIRTUAL_REQUIRED_CALL(_shaped_text_get_parent, p_shaped, ret); + GDVIRTUAL_CALL(_shaped_text_get_parent, p_shaped, ret); return ret; } @@ -1202,7 +1202,7 @@ double TextServerExtension::shaped_text_tab_align(const RID &p_shaped, const Pac bool TextServerExtension::shaped_text_shape(const RID &p_shaped) { bool ret = false; - GDVIRTUAL_REQUIRED_CALL(_shaped_text_shape, p_shaped, ret); + GDVIRTUAL_CALL(_shaped_text_shape, p_shaped, ret); return ret; } @@ -1220,31 +1220,31 @@ bool TextServerExtension::shaped_text_update_justification_ops(const RID &p_shap bool TextServerExtension::shaped_text_is_ready(const RID &p_shaped) const { bool ret = false; - GDVIRTUAL_REQUIRED_CALL(_shaped_text_is_ready, p_shaped, ret); + GDVIRTUAL_CALL(_shaped_text_is_ready, p_shaped, ret); return ret; } const Glyph *TextServerExtension::shaped_text_get_glyphs(const RID &p_shaped) const { GDExtensionConstPtr<const Glyph> ret; - GDVIRTUAL_REQUIRED_CALL(_shaped_text_get_glyphs, p_shaped, ret); + GDVIRTUAL_CALL(_shaped_text_get_glyphs, p_shaped, ret); return ret; } const Glyph *TextServerExtension::shaped_text_sort_logical(const RID &p_shaped) { GDExtensionConstPtr<const Glyph> ret; - GDVIRTUAL_REQUIRED_CALL(_shaped_text_sort_logical, p_shaped, ret); + GDVIRTUAL_CALL(_shaped_text_sort_logical, p_shaped, ret); return ret; } int64_t TextServerExtension::shaped_text_get_glyph_count(const RID &p_shaped) const { int64_t ret = 0; - GDVIRTUAL_REQUIRED_CALL(_shaped_text_get_glyph_count, p_shaped, ret); + GDVIRTUAL_CALL(_shaped_text_get_glyph_count, p_shaped, ret); return ret; } Vector2i TextServerExtension::shaped_text_get_range(const RID &p_shaped) const { Vector2i ret; - GDVIRTUAL_REQUIRED_CALL(_shaped_text_get_range, p_shaped, ret); + GDVIRTUAL_CALL(_shaped_text_get_range, p_shaped, ret); return ret; } @@ -1274,25 +1274,25 @@ PackedInt32Array TextServerExtension::shaped_text_get_word_breaks(const RID &p_s int64_t TextServerExtension::shaped_text_get_trim_pos(const RID &p_shaped) const { int64_t ret = -1; - GDVIRTUAL_REQUIRED_CALL(_shaped_text_get_trim_pos, p_shaped, ret); + GDVIRTUAL_CALL(_shaped_text_get_trim_pos, p_shaped, ret); return ret; } int64_t TextServerExtension::shaped_text_get_ellipsis_pos(const RID &p_shaped) const { int64_t ret = -1; - GDVIRTUAL_REQUIRED_CALL(_shaped_text_get_ellipsis_pos, p_shaped, ret); + GDVIRTUAL_CALL(_shaped_text_get_ellipsis_pos, p_shaped, ret); return ret; } const Glyph *TextServerExtension::shaped_text_get_ellipsis_glyphs(const RID &p_shaped) const { GDExtensionConstPtr<const Glyph> ret; - GDVIRTUAL_REQUIRED_CALL(_shaped_text_get_ellipsis_glyphs, p_shaped, ret); + GDVIRTUAL_CALL(_shaped_text_get_ellipsis_glyphs, p_shaped, ret); return ret; } int64_t TextServerExtension::shaped_text_get_ellipsis_glyph_count(const RID &p_shaped) const { int64_t ret = -1; - GDVIRTUAL_REQUIRED_CALL(_shaped_text_get_ellipsis_glyph_count, p_shaped, ret); + GDVIRTUAL_CALL(_shaped_text_get_ellipsis_glyph_count, p_shaped, ret); return ret; } @@ -1302,61 +1302,61 @@ void TextServerExtension::shaped_text_overrun_trim_to_width(const RID &p_shaped_ Array TextServerExtension::shaped_text_get_objects(const RID &p_shaped) const { Array ret; - GDVIRTUAL_REQUIRED_CALL(_shaped_text_get_objects, p_shaped, ret); + GDVIRTUAL_CALL(_shaped_text_get_objects, p_shaped, ret); return ret; } Rect2 TextServerExtension::shaped_text_get_object_rect(const RID &p_shaped, const Variant &p_key) const { Rect2 ret; - GDVIRTUAL_REQUIRED_CALL(_shaped_text_get_object_rect, p_shaped, p_key, ret); + GDVIRTUAL_CALL(_shaped_text_get_object_rect, p_shaped, p_key, ret); return ret; } Vector2i TextServerExtension::shaped_text_get_object_range(const RID &p_shaped, const Variant &p_key) const { Vector2i ret; - GDVIRTUAL_REQUIRED_CALL(_shaped_text_get_object_range, p_shaped, p_key, ret); + GDVIRTUAL_CALL(_shaped_text_get_object_range, p_shaped, p_key, ret); return ret; } int64_t TextServerExtension::shaped_text_get_object_glyph(const RID &p_shaped, const Variant &p_key) const { int64_t ret = -1; - GDVIRTUAL_REQUIRED_CALL(_shaped_text_get_object_glyph, p_shaped, p_key, ret); + GDVIRTUAL_CALL(_shaped_text_get_object_glyph, p_shaped, p_key, ret); return ret; } Size2 TextServerExtension::shaped_text_get_size(const RID &p_shaped) const { Size2 ret; - GDVIRTUAL_REQUIRED_CALL(_shaped_text_get_size, p_shaped, ret); + GDVIRTUAL_CALL(_shaped_text_get_size, p_shaped, ret); return ret; } double TextServerExtension::shaped_text_get_ascent(const RID &p_shaped) const { double ret = 0; - GDVIRTUAL_REQUIRED_CALL(_shaped_text_get_ascent, p_shaped, ret); + GDVIRTUAL_CALL(_shaped_text_get_ascent, p_shaped, ret); return ret; } double TextServerExtension::shaped_text_get_descent(const RID &p_shaped) const { double ret = 0; - GDVIRTUAL_REQUIRED_CALL(_shaped_text_get_descent, p_shaped, ret); + GDVIRTUAL_CALL(_shaped_text_get_descent, p_shaped, ret); return ret; } double TextServerExtension::shaped_text_get_width(const RID &p_shaped) const { double ret = 0; - GDVIRTUAL_REQUIRED_CALL(_shaped_text_get_width, p_shaped, ret); + GDVIRTUAL_CALL(_shaped_text_get_width, p_shaped, ret); return ret; } double TextServerExtension::shaped_text_get_underline_position(const RID &p_shaped) const { double ret = 0; - GDVIRTUAL_REQUIRED_CALL(_shaped_text_get_underline_position, p_shaped, ret); + GDVIRTUAL_CALL(_shaped_text_get_underline_position, p_shaped, ret); return ret; } double TextServerExtension::shaped_text_get_underline_thickness(const RID &p_shaped) const { double ret = 0; - GDVIRTUAL_REQUIRED_CALL(_shaped_text_get_underline_thickness, p_shaped, ret); + GDVIRTUAL_CALL(_shaped_text_get_underline_thickness, p_shaped, ret); return ret; } diff --git a/servers/text/text_server_extension.h b/servers/text/text_server_extension.h index 52654c010c..bd803be8aa 100644 --- a/servers/text/text_server_extension.h +++ b/servers/text/text_server_extension.h @@ -49,15 +49,15 @@ public: virtual bool has_feature(Feature p_feature) const override; virtual String get_name() const override; virtual int64_t get_features() const override; - GDVIRTUAL1RC(bool, _has_feature, Feature); - GDVIRTUAL0RC(String, _get_name); - GDVIRTUAL0RC(int64_t, _get_features); + GDVIRTUAL1RC_REQUIRED(bool, _has_feature, Feature); + GDVIRTUAL0RC_REQUIRED(String, _get_name); + GDVIRTUAL0RC_REQUIRED(int64_t, _get_features); virtual void free_rid(const RID &p_rid) override; virtual bool has(const RID &p_rid) override; virtual bool load_support_data(const String &p_filename) override; - GDVIRTUAL1(_free_rid, RID); - GDVIRTUAL1R(bool, _has, RID); + GDVIRTUAL1_REQUIRED(_free_rid, RID); + GDVIRTUAL1R_REQUIRED(bool, _has, RID); GDVIRTUAL1R(bool, _load_support_data, const String &); virtual String get_support_data_filename() const override; @@ -78,7 +78,7 @@ public: /* Font interface */ virtual RID create_font() override; - GDVIRTUAL0R(RID, _create_font); + GDVIRTUAL0R_REQUIRED(RID, _create_font); virtual RID create_font_linked_variation(const RID &p_font_rid) override; GDVIRTUAL1R(RID, _create_font_linked_variation, RID); @@ -155,13 +155,13 @@ public: virtual void font_set_fixed_size(const RID &p_font_rid, int64_t p_fixed_size) override; virtual int64_t font_get_fixed_size(const RID &p_font_rid) const override; - GDVIRTUAL2(_font_set_fixed_size, RID, int64_t); - GDVIRTUAL1RC(int64_t, _font_get_fixed_size, RID); + GDVIRTUAL2_REQUIRED(_font_set_fixed_size, RID, int64_t); + GDVIRTUAL1RC_REQUIRED(int64_t, _font_get_fixed_size, RID); virtual void font_set_fixed_size_scale_mode(const RID &p_font_rid, FixedSizeScaleMode p_fixed_size_scale) override; virtual FixedSizeScaleMode font_get_fixed_size_scale_mode(const RID &p_font_rid) const override; - GDVIRTUAL2(_font_set_fixed_size_scale_mode, RID, FixedSizeScaleMode); - GDVIRTUAL1RC(FixedSizeScaleMode, _font_get_fixed_size_scale_mode, RID); + GDVIRTUAL2_REQUIRED(_font_set_fixed_size_scale_mode, RID, FixedSizeScaleMode); + GDVIRTUAL1RC_REQUIRED(FixedSizeScaleMode, _font_get_fixed_size_scale_mode, RID); virtual void font_set_subpixel_positioning(const RID &p_font_rid, SubpixelPositioning p_subpixel) override; virtual SubpixelPositioning font_get_subpixel_positioning(const RID &p_font_rid) const override; @@ -216,46 +216,46 @@ public: virtual TypedArray<Vector2i> font_get_size_cache_list(const RID &p_font_rid) const override; virtual void font_clear_size_cache(const RID &p_font_rid) override; virtual void font_remove_size_cache(const RID &p_font_rid, const Vector2i &p_size) override; - GDVIRTUAL1RC(TypedArray<Vector2i>, _font_get_size_cache_list, RID); - GDVIRTUAL1(_font_clear_size_cache, RID); - GDVIRTUAL2(_font_remove_size_cache, RID, const Vector2i &); + GDVIRTUAL1RC_REQUIRED(TypedArray<Vector2i>, _font_get_size_cache_list, RID); + GDVIRTUAL1_REQUIRED(_font_clear_size_cache, RID); + GDVIRTUAL2_REQUIRED(_font_remove_size_cache, RID, const Vector2i &); virtual void font_set_ascent(const RID &p_font_rid, int64_t p_size, double p_ascent) override; virtual double font_get_ascent(const RID &p_font_rid, int64_t p_size) const override; - GDVIRTUAL3(_font_set_ascent, RID, int64_t, double); - GDVIRTUAL2RC(double, _font_get_ascent, RID, int64_t); + GDVIRTUAL3_REQUIRED(_font_set_ascent, RID, int64_t, double); + GDVIRTUAL2RC_REQUIRED(double, _font_get_ascent, RID, int64_t); virtual void font_set_descent(const RID &p_font_rid, int64_t p_size, double p_descent) override; virtual double font_get_descent(const RID &p_font_rid, int64_t p_size) const override; - GDVIRTUAL3(_font_set_descent, RID, int64_t, double); - GDVIRTUAL2RC(double, _font_get_descent, RID, int64_t); + GDVIRTUAL3_REQUIRED(_font_set_descent, RID, int64_t, double); + GDVIRTUAL2RC_REQUIRED(double, _font_get_descent, RID, int64_t); virtual void font_set_underline_position(const RID &p_font_rid, int64_t p_size, double p_underline_position) override; virtual double font_get_underline_position(const RID &p_font_rid, int64_t p_size) const override; - GDVIRTUAL3(_font_set_underline_position, RID, int64_t, double); - GDVIRTUAL2RC(double, _font_get_underline_position, RID, int64_t); + GDVIRTUAL3_REQUIRED(_font_set_underline_position, RID, int64_t, double); + GDVIRTUAL2RC_REQUIRED(double, _font_get_underline_position, RID, int64_t); virtual void font_set_underline_thickness(const RID &p_font_rid, int64_t p_size, double p_underline_thickness) override; virtual double font_get_underline_thickness(const RID &p_font_rid, int64_t p_size) const override; - GDVIRTUAL3(_font_set_underline_thickness, RID, int64_t, double); - GDVIRTUAL2RC(double, _font_get_underline_thickness, RID, int64_t); + GDVIRTUAL3_REQUIRED(_font_set_underline_thickness, RID, int64_t, double); + GDVIRTUAL2RC_REQUIRED(double, _font_get_underline_thickness, RID, int64_t); virtual void font_set_scale(const RID &p_font_rid, int64_t p_size, double p_scale) override; virtual double font_get_scale(const RID &p_font_rid, int64_t p_size) const override; - GDVIRTUAL3(_font_set_scale, RID, int64_t, double); - GDVIRTUAL2RC(double, _font_get_scale, RID, int64_t); + GDVIRTUAL3_REQUIRED(_font_set_scale, RID, int64_t, double); + GDVIRTUAL2RC_REQUIRED(double, _font_get_scale, RID, int64_t); virtual int64_t font_get_texture_count(const RID &p_font_rid, const Vector2i &p_size) const override; virtual void font_clear_textures(const RID &p_font_rid, const Vector2i &p_size) override; virtual void font_remove_texture(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index) override; - GDVIRTUAL2RC(int64_t, _font_get_texture_count, RID, const Vector2i &); - GDVIRTUAL2(_font_clear_textures, RID, const Vector2i &); - GDVIRTUAL3(_font_remove_texture, RID, const Vector2i &, int64_t); + GDVIRTUAL2RC_REQUIRED(int64_t, _font_get_texture_count, RID, const Vector2i &); + GDVIRTUAL2_REQUIRED(_font_clear_textures, RID, const Vector2i &); + GDVIRTUAL3_REQUIRED(_font_remove_texture, RID, const Vector2i &, int64_t); virtual void font_set_texture_image(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index, const Ref<Image> &p_image) override; virtual Ref<Image> font_get_texture_image(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index) const override; - GDVIRTUAL4(_font_set_texture_image, RID, const Vector2i &, int64_t, const Ref<Image> &); - GDVIRTUAL3RC(Ref<Image>, _font_get_texture_image, RID, const Vector2i &, int64_t); + GDVIRTUAL4_REQUIRED(_font_set_texture_image, RID, const Vector2i &, int64_t, const Ref<Image> &); + GDVIRTUAL3RC_REQUIRED(Ref<Image>, _font_get_texture_image, RID, const Vector2i &, int64_t); virtual void font_set_texture_offsets(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index, const PackedInt32Array &p_offset) override; virtual PackedInt32Array font_get_texture_offsets(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index) const override; @@ -265,40 +265,40 @@ public: virtual PackedInt32Array font_get_glyph_list(const RID &p_font_rid, const Vector2i &p_size) const override; virtual void font_clear_glyphs(const RID &p_font_rid, const Vector2i &p_size) override; virtual void font_remove_glyph(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) override; - GDVIRTUAL2RC(PackedInt32Array, _font_get_glyph_list, RID, const Vector2i &); - GDVIRTUAL2(_font_clear_glyphs, RID, const Vector2i &); - GDVIRTUAL3(_font_remove_glyph, RID, const Vector2i &, int64_t); + GDVIRTUAL2RC_REQUIRED(PackedInt32Array, _font_get_glyph_list, RID, const Vector2i &); + GDVIRTUAL2_REQUIRED(_font_clear_glyphs, RID, const Vector2i &); + GDVIRTUAL3_REQUIRED(_font_remove_glyph, RID, const Vector2i &, int64_t); virtual Vector2 font_get_glyph_advance(const RID &p_font_rid, int64_t p_size, int64_t p_glyph) const override; virtual void font_set_glyph_advance(const RID &p_font_rid, int64_t p_size, int64_t p_glyph, const Vector2 &p_advance) override; - GDVIRTUAL3RC(Vector2, _font_get_glyph_advance, RID, int64_t, int64_t); - GDVIRTUAL4(_font_set_glyph_advance, RID, int64_t, int64_t, const Vector2 &); + GDVIRTUAL3RC_REQUIRED(Vector2, _font_get_glyph_advance, RID, int64_t, int64_t); + GDVIRTUAL4_REQUIRED(_font_set_glyph_advance, RID, int64_t, int64_t, const Vector2 &); virtual Vector2 font_get_glyph_offset(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const override; virtual void font_set_glyph_offset(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph, const Vector2 &p_offset) override; - GDVIRTUAL3RC(Vector2, _font_get_glyph_offset, RID, const Vector2i &, int64_t); - GDVIRTUAL4(_font_set_glyph_offset, RID, const Vector2i &, int64_t, const Vector2 &); + GDVIRTUAL3RC_REQUIRED(Vector2, _font_get_glyph_offset, RID, const Vector2i &, int64_t); + GDVIRTUAL4_REQUIRED(_font_set_glyph_offset, RID, const Vector2i &, int64_t, const Vector2 &); virtual Vector2 font_get_glyph_size(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const override; virtual void font_set_glyph_size(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph, const Vector2 &p_gl_size) override; - GDVIRTUAL3RC(Vector2, _font_get_glyph_size, RID, const Vector2i &, int64_t); - GDVIRTUAL4(_font_set_glyph_size, RID, const Vector2i &, int64_t, const Vector2 &); + GDVIRTUAL3RC_REQUIRED(Vector2, _font_get_glyph_size, RID, const Vector2i &, int64_t); + GDVIRTUAL4_REQUIRED(_font_set_glyph_size, RID, const Vector2i &, int64_t, const Vector2 &); virtual Rect2 font_get_glyph_uv_rect(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const override; virtual void font_set_glyph_uv_rect(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph, const Rect2 &p_uv_rect) override; - GDVIRTUAL3RC(Rect2, _font_get_glyph_uv_rect, RID, const Vector2i &, int64_t); - GDVIRTUAL4(_font_set_glyph_uv_rect, RID, const Vector2i &, int64_t, const Rect2 &); + GDVIRTUAL3RC_REQUIRED(Rect2, _font_get_glyph_uv_rect, RID, const Vector2i &, int64_t); + GDVIRTUAL4_REQUIRED(_font_set_glyph_uv_rect, RID, const Vector2i &, int64_t, const Rect2 &); virtual int64_t font_get_glyph_texture_idx(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const override; virtual void font_set_glyph_texture_idx(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph, int64_t p_texture_idx) override; - GDVIRTUAL3RC(int64_t, _font_get_glyph_texture_idx, RID, const Vector2i &, int64_t); - GDVIRTUAL4(_font_set_glyph_texture_idx, RID, const Vector2i &, int64_t, int64_t); + GDVIRTUAL3RC_REQUIRED(int64_t, _font_get_glyph_texture_idx, RID, const Vector2i &, int64_t); + GDVIRTUAL4_REQUIRED(_font_set_glyph_texture_idx, RID, const Vector2i &, int64_t, int64_t); virtual RID font_get_glyph_texture_rid(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const override; - GDVIRTUAL3RC(RID, _font_get_glyph_texture_rid, RID, const Vector2i &, int64_t); + GDVIRTUAL3RC_REQUIRED(RID, _font_get_glyph_texture_rid, RID, const Vector2i &, int64_t); virtual Size2 font_get_glyph_texture_size(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const override; - GDVIRTUAL3RC(Size2, _font_get_glyph_texture_size, RID, const Vector2i &, int64_t); + GDVIRTUAL3RC_REQUIRED(Size2, _font_get_glyph_texture_size, RID, const Vector2i &, int64_t); virtual Dictionary font_get_glyph_contours(const RID &p_font, int64_t p_size, int64_t p_index) const override; GDVIRTUAL3RC(Dictionary, _font_get_glyph_contours, RID, int64_t, int64_t); @@ -316,17 +316,17 @@ public: GDVIRTUAL3RC(Vector2, _font_get_kerning, RID, int64_t, const Vector2i &); virtual int64_t font_get_glyph_index(const RID &p_font_rid, int64_t p_size, int64_t p_char, int64_t p_variation_selector = 0) const override; - GDVIRTUAL4RC(int64_t, _font_get_glyph_index, RID, int64_t, int64_t, int64_t); + GDVIRTUAL4RC_REQUIRED(int64_t, _font_get_glyph_index, RID, int64_t, int64_t, int64_t); virtual int64_t font_get_char_from_glyph_index(const RID &p_font_rid, int64_t p_size, int64_t p_glyph_index) const override; - GDVIRTUAL3RC(int64_t, _font_get_char_from_glyph_index, RID, int64_t, int64_t); + GDVIRTUAL3RC_REQUIRED(int64_t, _font_get_char_from_glyph_index, RID, int64_t, int64_t); virtual bool font_has_char(const RID &p_font_rid, int64_t p_char) const override; virtual String font_get_supported_chars(const RID &p_font_rid) const override; virtual PackedInt32Array font_get_supported_glyphs(const RID &p_font_rid) const override; - GDVIRTUAL2RC(bool, _font_has_char, RID, int64_t); - GDVIRTUAL1RC(String, _font_get_supported_chars, RID); - GDVIRTUAL1RC(PackedInt32Array, _font_get_supported_glyphs, RID); + GDVIRTUAL2RC_REQUIRED(bool, _font_has_char, RID, int64_t); + GDVIRTUAL1RC_REQUIRED(String, _font_get_supported_chars, RID); + GDVIRTUAL1RC_REQUIRED(PackedInt32Array, _font_get_supported_glyphs, RID); virtual void font_render_range(const RID &p_font, const Vector2i &p_size, int64_t p_start, int64_t p_end) override; virtual void font_render_glyph(const RID &p_font_rid, const Vector2i &p_size, int64_t p_index) override; @@ -335,8 +335,8 @@ public: virtual void font_draw_glyph(const RID &p_font, const RID &p_canvas, int64_t p_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color = Color(1, 1, 1)) const override; virtual void font_draw_glyph_outline(const RID &p_font, const RID &p_canvas, int64_t p_size, int64_t p_outline_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color = Color(1, 1, 1)) const override; - GDVIRTUAL6C(_font_draw_glyph, RID, RID, int64_t, const Vector2 &, int64_t, const Color &); - GDVIRTUAL7C(_font_draw_glyph_outline, RID, RID, int64_t, int64_t, const Vector2 &, int64_t, const Color &); + GDVIRTUAL6C_REQUIRED(_font_draw_glyph, RID, RID, int64_t, const Vector2 &, int64_t, const Color &); + GDVIRTUAL7C_REQUIRED(_font_draw_glyph_outline, RID, RID, int64_t, int64_t, const Vector2 &, int64_t, const Color &); virtual bool font_is_language_supported(const RID &p_font_rid, const String &p_language) const override; virtual void font_set_language_support_override(const RID &p_font_rid, const String &p_language, bool p_supported) override; @@ -383,10 +383,10 @@ public: /* Shaped text buffer interface */ virtual RID create_shaped_text(Direction p_direction = DIRECTION_AUTO, Orientation p_orientation = ORIENTATION_HORIZONTAL) override; - GDVIRTUAL2R(RID, _create_shaped_text, Direction, Orientation); + GDVIRTUAL2R_REQUIRED(RID, _create_shaped_text, Direction, Orientation); virtual void shaped_text_clear(const RID &p_shaped) override; - GDVIRTUAL1(_shaped_text_clear, RID); + GDVIRTUAL1_REQUIRED(_shaped_text_clear, RID); virtual void shaped_text_set_direction(const RID &p_shaped, Direction p_direction = DIRECTION_AUTO) override; virtual Direction shaped_text_get_direction(const RID &p_shaped) const override; @@ -431,21 +431,21 @@ public: virtual bool shaped_text_add_string(const RID &p_shaped, const String &p_text, const TypedArray<RID> &p_fonts, int64_t p_size, const Dictionary &p_opentype_features = Dictionary(), const String &p_language = "", const Variant &p_meta = Variant()) override; virtual bool shaped_text_add_object(const RID &p_shaped, const Variant &p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER, int64_t p_length = 1, double p_baseline = 0.0) override; virtual bool shaped_text_resize_object(const RID &p_shaped, const Variant &p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER, double p_baseline = 0.0) override; - GDVIRTUAL7R(bool, _shaped_text_add_string, RID, const String &, const TypedArray<RID> &, int64_t, const Dictionary &, const String &, const Variant &); - GDVIRTUAL6R(bool, _shaped_text_add_object, RID, const Variant &, const Size2 &, InlineAlignment, int64_t, double); - GDVIRTUAL5R(bool, _shaped_text_resize_object, RID, const Variant &, const Size2 &, InlineAlignment, double); + GDVIRTUAL7R_REQUIRED(bool, _shaped_text_add_string, RID, const String &, const TypedArray<RID> &, int64_t, const Dictionary &, const String &, const Variant &); + GDVIRTUAL6R_REQUIRED(bool, _shaped_text_add_object, RID, const Variant &, const Size2 &, InlineAlignment, int64_t, double); + GDVIRTUAL5R_REQUIRED(bool, _shaped_text_resize_object, RID, const Variant &, const Size2 &, InlineAlignment, double); virtual int64_t shaped_get_span_count(const RID &p_shaped) const override; virtual Variant shaped_get_span_meta(const RID &p_shaped, int64_t p_index) const override; virtual void shaped_set_span_update_font(const RID &p_shaped, int64_t p_index, const TypedArray<RID> &p_fonts, int64_t p_size, const Dictionary &p_opentype_features = Dictionary()) override; - GDVIRTUAL1RC(int64_t, _shaped_get_span_count, RID); - GDVIRTUAL2RC(Variant, _shaped_get_span_meta, RID, int64_t); - GDVIRTUAL5(_shaped_set_span_update_font, RID, int64_t, const TypedArray<RID> &, int64_t, const Dictionary &); + GDVIRTUAL1RC_REQUIRED(int64_t, _shaped_get_span_count, RID); + GDVIRTUAL2RC_REQUIRED(Variant, _shaped_get_span_meta, RID, int64_t); + GDVIRTUAL5_REQUIRED(_shaped_set_span_update_font, RID, int64_t, const TypedArray<RID> &, int64_t, const Dictionary &); virtual RID shaped_text_substr(const RID &p_shaped, int64_t p_start, int64_t p_length) const override; virtual RID shaped_text_get_parent(const RID &p_shaped) const override; - GDVIRTUAL3RC(RID, _shaped_text_substr, RID, int64_t, int64_t); - GDVIRTUAL1RC(RID, _shaped_text_get_parent, RID); + GDVIRTUAL3RC_REQUIRED(RID, _shaped_text_substr, RID, int64_t, int64_t); + GDVIRTUAL1RC_REQUIRED(RID, _shaped_text_get_parent, RID); virtual double shaped_text_fit_to_width(const RID &p_shaped, double p_width, BitField<TextServer::JustificationFlag> p_jst_flags = JUSTIFICATION_WORD_BOUND | JUSTIFICATION_KASHIDA) override; virtual double shaped_text_tab_align(const RID &p_shaped, const PackedFloat32Array &p_tab_stops) override; @@ -455,22 +455,22 @@ public: virtual bool shaped_text_shape(const RID &p_shaped) override; virtual bool shaped_text_update_breaks(const RID &p_shaped) override; virtual bool shaped_text_update_justification_ops(const RID &p_shaped) override; - GDVIRTUAL1R(bool, _shaped_text_shape, RID); + GDVIRTUAL1R_REQUIRED(bool, _shaped_text_shape, RID); GDVIRTUAL1R(bool, _shaped_text_update_breaks, RID); GDVIRTUAL1R(bool, _shaped_text_update_justification_ops, RID); virtual bool shaped_text_is_ready(const RID &p_shaped) const override; - GDVIRTUAL1RC(bool, _shaped_text_is_ready, RID); + GDVIRTUAL1RC_REQUIRED(bool, _shaped_text_is_ready, RID); virtual const Glyph *shaped_text_get_glyphs(const RID &p_shaped) const override; virtual const Glyph *shaped_text_sort_logical(const RID &p_shaped) override; virtual int64_t shaped_text_get_glyph_count(const RID &p_shaped) const override; - GDVIRTUAL1RC(GDExtensionConstPtr<const Glyph>, _shaped_text_get_glyphs, RID); - GDVIRTUAL1R(GDExtensionConstPtr<const Glyph>, _shaped_text_sort_logical, RID); - GDVIRTUAL1RC(int64_t, _shaped_text_get_glyph_count, RID); + GDVIRTUAL1RC_REQUIRED(GDExtensionConstPtr<const Glyph>, _shaped_text_get_glyphs, RID); + GDVIRTUAL1R_REQUIRED(GDExtensionConstPtr<const Glyph>, _shaped_text_sort_logical, RID); + GDVIRTUAL1RC_REQUIRED(int64_t, _shaped_text_get_glyph_count, RID); virtual Vector2i shaped_text_get_range(const RID &p_shaped) const override; - GDVIRTUAL1RC(Vector2i, _shaped_text_get_range, RID); + GDVIRTUAL1RC_REQUIRED(Vector2i, _shaped_text_get_range, RID); virtual PackedInt32Array shaped_text_get_line_breaks_adv(const RID &p_shaped, const PackedFloat32Array &p_width, int64_t p_start = 0, bool p_once = true, BitField<TextServer::LineBreakFlag> p_break_flags = BREAK_MANDATORY | BREAK_WORD_BOUND) const override; virtual PackedInt32Array shaped_text_get_line_breaks(const RID &p_shaped, double p_width, int64_t p_start = 0, BitField<TextServer::LineBreakFlag> p_break_flags = BREAK_MANDATORY | BREAK_WORD_BOUND) const override; @@ -483,10 +483,10 @@ public: virtual int64_t shaped_text_get_ellipsis_pos(const RID &p_shaped) const override; virtual const Glyph *shaped_text_get_ellipsis_glyphs(const RID &p_shaped) const override; virtual int64_t shaped_text_get_ellipsis_glyph_count(const RID &p_shaped) const override; - GDVIRTUAL1RC(int64_t, _shaped_text_get_trim_pos, RID); - GDVIRTUAL1RC(int64_t, _shaped_text_get_ellipsis_pos, RID); - GDVIRTUAL1RC(GDExtensionConstPtr<const Glyph>, _shaped_text_get_ellipsis_glyphs, RID); - GDVIRTUAL1RC(int64_t, _shaped_text_get_ellipsis_glyph_count, RID); + GDVIRTUAL1RC_REQUIRED(int64_t, _shaped_text_get_trim_pos, RID); + GDVIRTUAL1RC_REQUIRED(int64_t, _shaped_text_get_ellipsis_pos, RID); + GDVIRTUAL1RC_REQUIRED(GDExtensionConstPtr<const Glyph>, _shaped_text_get_ellipsis_glyphs, RID); + GDVIRTUAL1RC_REQUIRED(int64_t, _shaped_text_get_ellipsis_glyph_count, RID); virtual void shaped_text_overrun_trim_to_width(const RID &p_shaped, double p_width, BitField<TextServer::TextOverrunFlag> p_trim_flags) override; GDVIRTUAL3(_shaped_text_overrun_trim_to_width, RID, double, BitField<TextServer::TextOverrunFlag>); @@ -495,10 +495,10 @@ public: virtual Rect2 shaped_text_get_object_rect(const RID &p_shaped, const Variant &p_key) const override; virtual Vector2i shaped_text_get_object_range(const RID &p_shaped, const Variant &p_key) const override; virtual int64_t shaped_text_get_object_glyph(const RID &p_shaped, const Variant &p_key) const override; - GDVIRTUAL1RC(Array, _shaped_text_get_objects, RID); - GDVIRTUAL2RC(Rect2, _shaped_text_get_object_rect, RID, const Variant &); - GDVIRTUAL2RC(Vector2i, _shaped_text_get_object_range, RID, const Variant &); - GDVIRTUAL2RC(int64_t, _shaped_text_get_object_glyph, RID, const Variant &); + GDVIRTUAL1RC_REQUIRED(Array, _shaped_text_get_objects, RID); + GDVIRTUAL2RC_REQUIRED(Rect2, _shaped_text_get_object_rect, RID, const Variant &); + GDVIRTUAL2RC_REQUIRED(Vector2i, _shaped_text_get_object_range, RID, const Variant &); + GDVIRTUAL2RC_REQUIRED(int64_t, _shaped_text_get_object_glyph, RID, const Variant &); virtual Size2 shaped_text_get_size(const RID &p_shaped) const override; virtual double shaped_text_get_ascent(const RID &p_shaped) const override; @@ -506,12 +506,12 @@ public: virtual double shaped_text_get_width(const RID &p_shaped) const override; virtual double shaped_text_get_underline_position(const RID &p_shaped) const override; virtual double shaped_text_get_underline_thickness(const RID &p_shaped) const override; - GDVIRTUAL1RC(Size2, _shaped_text_get_size, RID); - GDVIRTUAL1RC(double, _shaped_text_get_ascent, RID); - GDVIRTUAL1RC(double, _shaped_text_get_descent, RID); - GDVIRTUAL1RC(double, _shaped_text_get_width, RID); - GDVIRTUAL1RC(double, _shaped_text_get_underline_position, RID); - GDVIRTUAL1RC(double, _shaped_text_get_underline_thickness, RID); + GDVIRTUAL1RC_REQUIRED(Size2, _shaped_text_get_size, RID); + GDVIRTUAL1RC_REQUIRED(double, _shaped_text_get_ascent, RID); + GDVIRTUAL1RC_REQUIRED(double, _shaped_text_get_descent, RID); + GDVIRTUAL1RC_REQUIRED(double, _shaped_text_get_width, RID); + GDVIRTUAL1RC_REQUIRED(double, _shaped_text_get_underline_position, RID); + GDVIRTUAL1RC_REQUIRED(double, _shaped_text_get_underline_thickness, RID); virtual Direction shaped_text_get_dominant_direction_in_range(const RID &p_shaped, int64_t p_start, int64_t p_end) const override; GDVIRTUAL3RC(int64_t, _shaped_text_get_dominant_direction_in_range, RID, int64_t, int64_t); diff --git a/thirdparty/README.md b/thirdparty/README.md index 4c47b91c8c..a219839afc 100644 --- a/thirdparty/README.md +++ b/thirdparty/README.md @@ -650,6 +650,10 @@ comments and a patch is provided in the `patches` folder. Collection of single-file libraries used in Godot components. +- `bcdec.h` + * Upstream: https://github.com/iOrange/bcdec + * Version: git (026acf98ea271045cb10713daa96ba98528badb7, 2022) + * License: MIT - `clipper.{cpp,hpp}` * Upstream: https://sourceforge.net/projects/polyclipping * Version: 6.4.2 (2017) + Godot changes (added optional exceptions handling) @@ -757,7 +761,7 @@ with the provided patch. ## openxr - Upstream: https://github.com/KhronosGroup/OpenXR-SDK -- Version: 1.1.38 (f90488c4fb1537f4256d09d4a4d3ad5543ebaf24, 2024) +- Version: 1.1.41 (7d1c0961351bac61fd7bb72d402649d5ac3f2935, 2024) - License: Apache 2.0 Files extracted from upstream source: @@ -873,23 +877,6 @@ They can be reapplied using the patches included in the `patches` folder, in order. -## squish - -- Upstream: https://sourceforge.net/projects/libsquish -- Version: 1.15 (r104, 2017) -- License: MIT - -Files extracted from upstream source: - -- `LICENSE.txt` -- All `.cpp`, `.h` and `.inl` files - -Some downstream changes have been made and are identified by -`// -- GODOT begin --` and `// -- GODOT end --` comments. -They can be reapplied using the patches included in the `patches` -folder. - - ## tinyexr - Upstream: https://github.com/syoyo/tinyexr diff --git a/thirdparty/misc/bcdec.h b/thirdparty/misc/bcdec.h new file mode 100644 index 0000000000..78074a0c90 --- /dev/null +++ b/thirdparty/misc/bcdec.h @@ -0,0 +1,1329 @@ +/* bcdec.h - v0.96 + provides functions to decompress blocks of BC compressed images + written by Sergii "iOrange" Kudlai in 2022 + + This library does not allocate memory and is trying to use as less stack as possible + + The library was never optimized specifically for speed but for the overall size + it has zero external dependencies and is not using any runtime functions + + Supported BC formats: + BC1 (also known as DXT1) + it's "binary alpha" variant BC1A (DXT1A) + BC2 (also known as DXT3) + BC3 (also known as DXT5) + BC4 (also known as ATI1N) + BC5 (also known as ATI2N) + BC6H (HDR format) + BC7 + + BC1/BC2/BC3/BC7 are expected to decompress into 4*4 RGBA blocks 8bit per component (32bit pixel) + BC4/BC5 are expected to decompress into 4*4 R/RG blocks 8bit per component (8bit and 16bit pixel) + BC6H is expected to decompress into 4*4 RGB blocks of either 32bit float or 16bit "half" per + component (96bit or 48bit pixel) + + For more info, issues and suggestions please visit https://github.com/iOrange/bcdec + + CREDITS: + Aras Pranckevicius (@aras-p) - BC1/BC3 decoders optimizations (up to 3x the speed) + - BC6H/BC7 bits pulling routines optimizations + - optimized BC6H by moving unquantize out of the loop + - Split BC6H decompression function into 'half' and + 'float' variants + + bugfixes: + @linkmauve + + LICENSE: See end of file for license information. +*/ + +#ifndef BCDEC_HEADER_INCLUDED +#define BCDEC_HEADER_INCLUDED + +/* if BCDEC_STATIC causes problems, try defining BCDECDEF to 'inline' or 'static inline' */ +#ifndef BCDECDEF +#ifdef BCDEC_STATIC +#define BCDECDEF static +#else +#ifdef __cplusplus +#define BCDECDEF extern "C" +#else +#define BCDECDEF extern +#endif +#endif +#endif + +/* Used information sources: + https://docs.microsoft.com/en-us/windows/win32/direct3d10/d3d10-graphics-programming-guide-resources-block-compression + https://docs.microsoft.com/en-us/windows/win32/direct3d11/bc6h-format + https://docs.microsoft.com/en-us/windows/win32/direct3d11/bc7-format + https://docs.microsoft.com/en-us/windows/win32/direct3d11/bc7-format-mode-reference + + ! WARNING ! Khronos's BPTC partitions tables contain mistakes, do not use them! + https://www.khronos.org/registry/DataFormat/specs/1.1/dataformat.1.1.html#BPTC + + ! Use tables from here instead ! + https://www.khronos.org/registry/OpenGL/extensions/ARB/ARB_texture_compression_bptc.txt + + Leaving it here as it's a nice read + https://fgiesen.wordpress.com/2021/10/04/gpu-bcn-decoding/ + + Fast half to float function from here + https://gist.github.com/rygorous/2144712 +*/ + +#define BCDEC_BC1_BLOCK_SIZE 8 +#define BCDEC_BC2_BLOCK_SIZE 16 +#define BCDEC_BC3_BLOCK_SIZE 16 +#define BCDEC_BC4_BLOCK_SIZE 8 +#define BCDEC_BC5_BLOCK_SIZE 16 +#define BCDEC_BC6H_BLOCK_SIZE 16 +#define BCDEC_BC7_BLOCK_SIZE 16 + +#define BCDEC_BC1_COMPRESSED_SIZE(w, h) ((((w)>>2)*((h)>>2))*BCDEC_BC1_BLOCK_SIZE) +#define BCDEC_BC2_COMPRESSED_SIZE(w, h) ((((w)>>2)*((h)>>2))*BCDEC_BC2_BLOCK_SIZE) +#define BCDEC_BC3_COMPRESSED_SIZE(w, h) ((((w)>>2)*((h)>>2))*BCDEC_BC3_BLOCK_SIZE) +#define BCDEC_BC4_COMPRESSED_SIZE(w, h) ((((w)>>2)*((h)>>2))*BCDEC_BC4_BLOCK_SIZE) +#define BCDEC_BC5_COMPRESSED_SIZE(w, h) ((((w)>>2)*((h)>>2))*BCDEC_BC5_BLOCK_SIZE) +#define BCDEC_BC6H_COMPRESSED_SIZE(w, h) ((((w)>>2)*((h)>>2))*BCDEC_BC6H_BLOCK_SIZE) +#define BCDEC_BC7_COMPRESSED_SIZE(w, h) ((((w)>>2)*((h)>>2))*BCDEC_BC7_BLOCK_SIZE) + +BCDECDEF void bcdec_bc1(const void* compressedBlock, void* decompressedBlock, int destinationPitch); +BCDECDEF void bcdec_bc2(const void* compressedBlock, void* decompressedBlock, int destinationPitch); +BCDECDEF void bcdec_bc3(const void* compressedBlock, void* decompressedBlock, int destinationPitch); +BCDECDEF void bcdec_bc4(const void* compressedBlock, void* decompressedBlock, int destinationPitch); +BCDECDEF void bcdec_bc5(const void* compressedBlock, void* decompressedBlock, int destinationPitch); +BCDECDEF void bcdec_bc6h_float(const void* compressedBlock, void* decompressedBlock, int destinationPitch, int isSigned); +BCDECDEF void bcdec_bc6h_half(const void* compressedBlock, void* decompressedBlock, int destinationPitch, int isSigned); +BCDECDEF void bcdec_bc7(const void* compressedBlock, void* decompressedBlock, int destinationPitch); + + +#ifdef BCDEC_IMPLEMENTATION + +static void bcdec__color_block(const void* compressedBlock, void* decompressedBlock, int destinationPitch, int onlyOpaqueMode) { + unsigned short c0, c1; + unsigned int refColors[4]; /* 0xAABBGGRR */ + unsigned char* dstColors; + unsigned int colorIndices; + int i, j, idx; + unsigned int r0, g0, b0, r1, g1, b1, r, g, b; + + c0 = ((unsigned short*)compressedBlock)[0]; + c1 = ((unsigned short*)compressedBlock)[1]; + + /* Expand 565 ref colors to 888 */ + r0 = (((c0 >> 11) & 0x1F) * 527 + 23) >> 6; + g0 = (((c0 >> 5) & 0x3F) * 259 + 33) >> 6; + b0 = ((c0 & 0x1F) * 527 + 23) >> 6; + refColors[0] = 0xFF000000 | (b0 << 16) | (g0 << 8) | r0; + + r1 = (((c1 >> 11) & 0x1F) * 527 + 23) >> 6; + g1 = (((c1 >> 5) & 0x3F) * 259 + 33) >> 6; + b1 = ((c1 & 0x1F) * 527 + 23) >> 6; + refColors[1] = 0xFF000000 | (b1 << 16) | (g1 << 8) | r1; + + if (c0 > c1 || onlyOpaqueMode) { /* Standard BC1 mode (also BC3 color block uses ONLY this mode) */ + /* color_2 = 2/3*color_0 + 1/3*color_1 + color_3 = 1/3*color_0 + 2/3*color_1 */ + r = (2 * r0 + r1 + 1) / 3; + g = (2 * g0 + g1 + 1) / 3; + b = (2 * b0 + b1 + 1) / 3; + refColors[2] = 0xFF000000 | (b << 16) | (g << 8) | r; + + r = (r0 + 2 * r1 + 1) / 3; + g = (g0 + 2 * g1 + 1) / 3; + b = (b0 + 2 * b1 + 1) / 3; + refColors[3] = 0xFF000000 | (b << 16) | (g << 8) | r; + } else { /* Quite rare BC1A mode */ + /* color_2 = 1/2*color_0 + 1/2*color_1; + color_3 = 0; */ + r = (r0 + r1 + 1) >> 1; + g = (g0 + g1 + 1) >> 1; + b = (b0 + b1 + 1) >> 1; + refColors[2] = 0xFF000000 | (b << 16) | (g << 8) | r; + + refColors[3] = 0x00000000; + } + + colorIndices = ((unsigned int*)compressedBlock)[1]; + + /* Fill out the decompressed color block */ + dstColors = (unsigned char*)decompressedBlock; + for (i = 0; i < 4; ++i) { + for (j = 0; j < 4; ++j) { + idx = colorIndices & 0x03; + ((unsigned int*)dstColors)[j] = refColors[idx]; + colorIndices >>= 2; + } + + dstColors += destinationPitch; + } +} + +static void bcdec__sharp_alpha_block(const void* compressedBlock, void* decompressedBlock, int destinationPitch) { + unsigned short* alpha; + unsigned char* decompressed; + int i, j; + + alpha = (unsigned short*)compressedBlock; + decompressed = (unsigned char*)decompressedBlock; + + for (i = 0; i < 4; ++i) { + for (j = 0; j < 4; ++j) { + decompressed[j * 4] = ((alpha[i] >> (4 * j)) & 0x0F) * 17; + } + + decompressed += destinationPitch; + } +} + +static void bcdec__smooth_alpha_block(const void* compressedBlock, void* decompressedBlock, int destinationPitch, int pixelSize) { + unsigned char* decompressed; + unsigned char alpha[8]; + int i, j; + unsigned long long block, indices; + + block = *(unsigned long long*)compressedBlock; + decompressed = (unsigned char*)decompressedBlock; + + alpha[0] = block & 0xFF; + alpha[1] = (block >> 8) & 0xFF; + + if (alpha[0] > alpha[1]) { + /* 6 interpolated alpha values. */ + alpha[2] = (6 * alpha[0] + alpha[1] + 1) / 7; /* 6/7*alpha_0 + 1/7*alpha_1 */ + alpha[3] = (5 * alpha[0] + 2 * alpha[1] + 1) / 7; /* 5/7*alpha_0 + 2/7*alpha_1 */ + alpha[4] = (4 * alpha[0] + 3 * alpha[1] + 1) / 7; /* 4/7*alpha_0 + 3/7*alpha_1 */ + alpha[5] = (3 * alpha[0] + 4 * alpha[1] + 1) / 7; /* 3/7*alpha_0 + 4/7*alpha_1 */ + alpha[6] = (2 * alpha[0] + 5 * alpha[1] + 1) / 7; /* 2/7*alpha_0 + 5/7*alpha_1 */ + alpha[7] = ( alpha[0] + 6 * alpha[1] + 1) / 7; /* 1/7*alpha_0 + 6/7*alpha_1 */ + } + else { + /* 4 interpolated alpha values. */ + alpha[2] = (4 * alpha[0] + alpha[1] + 1) / 5; /* 4/5*alpha_0 + 1/5*alpha_1 */ + alpha[3] = (3 * alpha[0] + 2 * alpha[1] + 1) / 5; /* 3/5*alpha_0 + 2/5*alpha_1 */ + alpha[4] = (2 * alpha[0] + 3 * alpha[1] + 1) / 5; /* 2/5*alpha_0 + 3/5*alpha_1 */ + alpha[5] = ( alpha[0] + 4 * alpha[1] + 1) / 5; /* 1/5*alpha_0 + 4/5*alpha_1 */ + alpha[6] = 0x00; + alpha[7] = 0xFF; + } + + indices = block >> 16; + for (i = 0; i < 4; ++i) { + for (j = 0; j < 4; ++j) { + decompressed[j * pixelSize] = alpha[indices & 0x07]; + indices >>= 3; + } + + decompressed += destinationPitch; + } +} + +typedef struct bcdec__bitstream { + unsigned long long low; + unsigned long long high; +} bcdec__bitstream_t; + +static int bcdec__bitstream_read_bits(bcdec__bitstream_t* bstream, int numBits) { + unsigned int mask = (1 << numBits) - 1; + /* Read the low N bits */ + unsigned int bits = (bstream->low & mask); + + bstream->low >>= numBits; + /* Put the low N bits of "high" into the high 64-N bits of "low". */ + bstream->low |= (bstream->high & mask) << (sizeof(bstream->high) * 8 - numBits); + bstream->high >>= numBits; + + return bits; +} + +static int bcdec__bitstream_read_bit(bcdec__bitstream_t* bstream) { + return bcdec__bitstream_read_bits(bstream, 1); +} + +/* reversed bits pulling, used in BC6H decoding + why ?? just why ??? */ +static int bcdec__bitstream_read_bits_r(bcdec__bitstream_t* bstream, int numBits) { + int bits = bcdec__bitstream_read_bits(bstream, numBits); + /* Reverse the bits. */ + int result = 0; + while (numBits--) { + result <<= 1; + result |= (bits & 1); + bits >>= 1; + } + return result; +} + + + +BCDECDEF void bcdec_bc1(const void* compressedBlock, void* decompressedBlock, int destinationPitch) { + bcdec__color_block(compressedBlock, decompressedBlock, destinationPitch, 0); +} + +BCDECDEF void bcdec_bc2(const void* compressedBlock, void* decompressedBlock, int destinationPitch) { + bcdec__color_block(((char*)compressedBlock) + 8, decompressedBlock, destinationPitch, 1); + bcdec__sharp_alpha_block(compressedBlock, ((char*)decompressedBlock) + 3, destinationPitch); +} + +BCDECDEF void bcdec_bc3(const void* compressedBlock, void* decompressedBlock, int destinationPitch) { + bcdec__color_block(((char*)compressedBlock) + 8, decompressedBlock, destinationPitch, 1); + bcdec__smooth_alpha_block(compressedBlock, ((char*)decompressedBlock) + 3, destinationPitch, 4); +} + +BCDECDEF void bcdec_bc4(const void* compressedBlock, void* decompressedBlock, int destinationPitch) { + bcdec__smooth_alpha_block(compressedBlock, decompressedBlock, destinationPitch, 1); +} + +BCDECDEF void bcdec_bc5(const void* compressedBlock, void* decompressedBlock, int destinationPitch) { + bcdec__smooth_alpha_block(compressedBlock, decompressedBlock, destinationPitch, 2); + bcdec__smooth_alpha_block(((char*)compressedBlock) + 8, ((char*)decompressedBlock) + 1, destinationPitch, 2); +} + +/* http://graphics.stanford.edu/~seander/bithacks.html#VariableSignExtend */ +static int bcdec__extend_sign(int val, int bits) { + return (val << (32 - bits)) >> (32 - bits); +} + +static int bcdec__transform_inverse(int val, int a0, int bits, int isSigned) { + /* If the precision of A0 is "p" bits, then the transform algorithm is: + B0 = (B0 + A0) & ((1 << p) - 1) */ + val = (val + a0) & ((1 << bits) - 1); + if (isSigned) { + val = bcdec__extend_sign(val, bits); + } + return val; +} + +/* pretty much copy-paste from documentation */ +static int bcdec__unquantize(int val, int bits, int isSigned) { + int unq, s = 0; + + if (!isSigned) { + if (bits >= 15) { + unq = val; + } else if (!val) { + unq = 0; + } else if (val == ((1 << bits) - 1)) { + unq = 0xFFFF; + } else { + unq = ((val << 16) + 0x8000) >> bits; + } + } else { + if (bits >= 16) { + unq = val; + } else { + if (val < 0) { + s = 1; + val = -val; + } + + if (val == 0) { + unq = 0; + } else if (val >= ((1 << (bits - 1)) - 1)) { + unq = 0x7FFF; + } else { + unq = ((val << 15) + 0x4000) >> (bits - 1); + } + + if (s) { + unq = -unq; + } + } + } + return unq; +} + +static int bcdec__interpolate(int a, int b, int* weights, int index) { + return (a * (64 - weights[index]) + b * weights[index] + 32) >> 6; +} + +static unsigned short bcdec__finish_unquantize(int val, int isSigned) { + int s; + + if (!isSigned) { + return (unsigned short)((val * 31) >> 6); /* scale the magnitude by 31 / 64 */ + } else { + val = (val < 0) ? -(((-val) * 31) >> 5) : (val * 31) >> 5; /* scale the magnitude by 31 / 32 */ + s = 0; + if (val < 0) { + s = 0x8000; + val = -val; + } + return (unsigned short)(s | val); + } +} + +/* modified half_to_float_fast4 from https://gist.github.com/rygorous/2144712 */ +static float bcdec__half_to_float_quick(unsigned short half) { + typedef union { + unsigned int u; + float f; + } FP32; + + static const FP32 magic = { 113 << 23 }; + static const unsigned int shifted_exp = 0x7c00 << 13; /* exponent mask after shift */ + FP32 o; + unsigned int exp; + + o.u = (half & 0x7fff) << 13; /* exponent/mantissa bits */ + exp = shifted_exp & o.u; /* just the exponent */ + o.u += (127 - 15) << 23; /* exponent adjust */ + + /* handle exponent special cases */ + if (exp == shifted_exp) { /* Inf/NaN? */ + o.u += (128 - 16) << 23; /* extra exp adjust */ + } else if (exp == 0) { /* Zero/Denormal? */ + o.u += 1 << 23; /* extra exp adjust */ + o.f -= magic.f; /* renormalize */ + } + + o.u |= (half & 0x8000) << 16; /* sign bit */ + return o.f; +} + +BCDECDEF void bcdec_bc6h_half(const void* compressedBlock, void* decompressedBlock, int destinationPitch, int isSigned) { + static char actual_bits_count[4][14] = { + { 10, 7, 11, 11, 11, 9, 8, 8, 8, 6, 10, 11, 12, 16 }, /* W */ + { 5, 6, 5, 4, 4, 5, 6, 5, 5, 6, 10, 9, 8, 4 }, /* dR */ + { 5, 6, 4, 5, 4, 5, 5, 6, 5, 6, 10, 9, 8, 4 }, /* dG */ + { 5, 6, 4, 4, 5, 5, 5, 5, 6, 6, 10, 9, 8, 4 } /* dB */ + }; + + /* There are 32 possible partition sets for a two-region tile. + Each 4x4 block represents a single shape. + Here also every fix-up index has MSB bit set. */ + static unsigned char partition_sets[32][4][4] = { + { {128, 0, 1, 1}, {0, 0, 1, 1}, { 0, 0, 1, 1}, {0, 0, 1, 129} }, /* 0 */ + { {128, 0, 0, 1}, {0, 0, 0, 1}, { 0, 0, 0, 1}, {0, 0, 0, 129} }, /* 1 */ + { {128, 1, 1, 1}, {0, 1, 1, 1}, { 0, 1, 1, 1}, {0, 1, 1, 129} }, /* 2 */ + { {128, 0, 0, 1}, {0, 0, 1, 1}, { 0, 0, 1, 1}, {0, 1, 1, 129} }, /* 3 */ + { {128, 0, 0, 0}, {0, 0, 0, 1}, { 0, 0, 0, 1}, {0, 0, 1, 129} }, /* 4 */ + { {128, 0, 1, 1}, {0, 1, 1, 1}, { 0, 1, 1, 1}, {1, 1, 1, 129} }, /* 5 */ + { {128, 0, 0, 1}, {0, 0, 1, 1}, { 0, 1, 1, 1}, {1, 1, 1, 129} }, /* 6 */ + { {128, 0, 0, 0}, {0, 0, 0, 1}, { 0, 0, 1, 1}, {0, 1, 1, 129} }, /* 7 */ + { {128, 0, 0, 0}, {0, 0, 0, 0}, { 0, 0, 0, 1}, {0, 0, 1, 129} }, /* 8 */ + { {128, 0, 1, 1}, {0, 1, 1, 1}, { 1, 1, 1, 1}, {1, 1, 1, 129} }, /* 9 */ + { {128, 0, 0, 0}, {0, 0, 0, 1}, { 0, 1, 1, 1}, {1, 1, 1, 129} }, /* 10 */ + { {128, 0, 0, 0}, {0, 0, 0, 0}, { 0, 0, 0, 1}, {0, 1, 1, 129} }, /* 11 */ + { {128, 0, 0, 1}, {0, 1, 1, 1}, { 1, 1, 1, 1}, {1, 1, 1, 129} }, /* 12 */ + { {128, 0, 0, 0}, {0, 0, 0, 0}, { 1, 1, 1, 1}, {1, 1, 1, 129} }, /* 13 */ + { {128, 0, 0, 0}, {1, 1, 1, 1}, { 1, 1, 1, 1}, {1, 1, 1, 129} }, /* 14 */ + { {128, 0, 0, 0}, {0, 0, 0, 0}, { 0, 0, 0, 0}, {1, 1, 1, 129} }, /* 15 */ + { {128, 0, 0, 0}, {1, 0, 0, 0}, { 1, 1, 1, 0}, {1, 1, 1, 129} }, /* 16 */ + { {128, 1, 129, 1}, {0, 0, 0, 1}, { 0, 0, 0, 0}, {0, 0, 0, 0} }, /* 17 */ + { {128, 0, 0, 0}, {0, 0, 0, 0}, {129, 0, 0, 0}, {1, 1, 1, 0} }, /* 18 */ + { {128, 1, 129, 1}, {0, 0, 1, 1}, { 0, 0, 0, 1}, {0, 0, 0, 0} }, /* 19 */ + { {128, 0, 129, 1}, {0, 0, 0, 1}, { 0, 0, 0, 0}, {0, 0, 0, 0} }, /* 20 */ + { {128, 0, 0, 0}, {1, 0, 0, 0}, {129, 1, 0, 0}, {1, 1, 1, 0} }, /* 21 */ + { {128, 0, 0, 0}, {0, 0, 0, 0}, {129, 0, 0, 0}, {1, 1, 0, 0} }, /* 22 */ + { {128, 1, 1, 1}, {0, 0, 1, 1}, { 0, 0, 1, 1}, {0, 0, 0, 129} }, /* 23 */ + { {128, 0, 129, 1}, {0, 0, 0, 1}, { 0, 0, 0, 1}, {0, 0, 0, 0} }, /* 24 */ + { {128, 0, 0, 0}, {1, 0, 0, 0}, {129, 0, 0, 0}, {1, 1, 0, 0} }, /* 25 */ + { {128, 1, 129, 0}, {0, 1, 1, 0}, { 0, 1, 1, 0}, {0, 1, 1, 0} }, /* 26 */ + { {128, 0, 129, 1}, {0, 1, 1, 0}, { 0, 1, 1, 0}, {1, 1, 0, 0} }, /* 27 */ + { {128, 0, 0, 1}, {0, 1, 1, 1}, {129, 1, 1, 0}, {1, 0, 0, 0} }, /* 28 */ + { {128, 0, 0, 0}, {1, 1, 1, 1}, {129, 1, 1, 1}, {0, 0, 0, 0} }, /* 29 */ + { {128, 1, 129, 1}, {0, 0, 0, 1}, { 1, 0, 0, 0}, {1, 1, 1, 0} }, /* 30 */ + { {128, 0, 129, 1}, {1, 0, 0, 1}, { 1, 0, 0, 1}, {1, 1, 0, 0} } /* 31 */ + }; + + static int aWeight3[8] = { 0, 9, 18, 27, 37, 46, 55, 64 }; + static int aWeight4[16] = { 0, 4, 9, 13, 17, 21, 26, 30, 34, 38, 43, 47, 51, 55, 60, 64 }; + + bcdec__bitstream_t bstream; + int mode, partition, numPartitions, i, j, partitionSet, indexBits, index, ep_i, actualBits0Mode; + int r[4], g[4], b[4]; /* wxyz */ + unsigned short* decompressed; + int* weights; + + decompressed = (unsigned short*)decompressedBlock; + + bstream.low = ((unsigned long long*)compressedBlock)[0]; + bstream.high = ((unsigned long long*)compressedBlock)[1]; + + r[0] = r[1] = r[2] = r[3] = 0; + g[0] = g[1] = g[2] = g[3] = 0; + b[0] = b[1] = b[2] = b[3] = 0; + + mode = bcdec__bitstream_read_bits(&bstream, 2); + if (mode > 1) { + mode |= (bcdec__bitstream_read_bits(&bstream, 3) << 2); + } + + /* modes >= 11 (10 in my code) are using 0 one, others will read it from the bitstream */ + partition = 0; + + switch (mode) { + /* mode 1 */ + case 0b00: { + /* Partitition indices: 46 bits + Partition: 5 bits + Color Endpoints: 75 bits (10.555, 10.555, 10.555) */ + g[2] |= bcdec__bitstream_read_bit(&bstream) << 4; /* gy[4] */ + b[2] |= bcdec__bitstream_read_bit(&bstream) << 4; /* by[4] */ + b[3] |= bcdec__bitstream_read_bit(&bstream) << 4; /* bz[4] */ + r[0] |= bcdec__bitstream_read_bits(&bstream, 10); /* rw[9:0] */ + g[0] |= bcdec__bitstream_read_bits(&bstream, 10); /* gw[9:0] */ + b[0] |= bcdec__bitstream_read_bits(&bstream, 10); /* bw[9:0] */ + r[1] |= bcdec__bitstream_read_bits(&bstream, 5); /* rx[4:0] */ + g[3] |= bcdec__bitstream_read_bit(&bstream) << 4; /* gz[4] */ + g[2] |= bcdec__bitstream_read_bits(&bstream, 4); /* gy[3:0] */ + g[1] |= bcdec__bitstream_read_bits(&bstream, 5); /* gx[4:0] */ + b[3] |= bcdec__bitstream_read_bit(&bstream); /* bz[0] */ + g[3] |= bcdec__bitstream_read_bits(&bstream, 4); /* gz[3:0] */ + b[1] |= bcdec__bitstream_read_bits(&bstream, 5); /* bx[4:0] */ + b[3] |= bcdec__bitstream_read_bit(&bstream) << 1; /* bz[1] */ + b[2] |= bcdec__bitstream_read_bits(&bstream, 4); /* by[3:0] */ + r[2] |= bcdec__bitstream_read_bits(&bstream, 5); /* ry[4:0] */ + b[3] |= bcdec__bitstream_read_bit(&bstream) << 2; /* bz[2] */ + r[3] |= bcdec__bitstream_read_bits(&bstream, 5); /* rz[4:0] */ + b[3] |= bcdec__bitstream_read_bit(&bstream) << 3; /* bz[3] */ + partition = bcdec__bitstream_read_bits(&bstream, 5); /* d[4:0] */ + mode = 0; + } break; + + /* mode 2 */ + case 0b01: { + /* Partitition indices: 46 bits + Partition: 5 bits + Color Endpoints: 75 bits (7666, 7666, 7666) */ + g[2] |= bcdec__bitstream_read_bit(&bstream) << 5; /* gy[5] */ + g[3] |= bcdec__bitstream_read_bit(&bstream) << 4; /* gz[4] */ + g[3] |= bcdec__bitstream_read_bit(&bstream) << 5; /* gz[5] */ + r[0] |= bcdec__bitstream_read_bits(&bstream, 7); /* rw[6:0] */ + b[3] |= bcdec__bitstream_read_bit(&bstream); /* bz[0] */ + b[3] |= bcdec__bitstream_read_bit(&bstream) << 1; /* bz[1] */ + b[2] |= bcdec__bitstream_read_bit(&bstream) << 4; /* by[4] */ + g[0] |= bcdec__bitstream_read_bits(&bstream, 7); /* gw[6:0] */ + b[2] |= bcdec__bitstream_read_bit(&bstream) << 5; /* by[5] */ + b[3] |= bcdec__bitstream_read_bit(&bstream) << 2; /* bz[2] */ + g[2] |= bcdec__bitstream_read_bit(&bstream) << 4; /* gy[4] */ + b[0] |= bcdec__bitstream_read_bits(&bstream, 7); /* bw[6:0] */ + b[3] |= bcdec__bitstream_read_bit(&bstream) << 3; /* bz[3] */ + b[3] |= bcdec__bitstream_read_bit(&bstream) << 5; /* bz[5] */ + b[3] |= bcdec__bitstream_read_bit(&bstream) << 4; /* bz[4] */ + r[1] |= bcdec__bitstream_read_bits(&bstream, 6); /* rx[5:0] */ + g[2] |= bcdec__bitstream_read_bits(&bstream, 4); /* gy[3:0] */ + g[1] |= bcdec__bitstream_read_bits(&bstream, 6); /* gx[5:0] */ + g[3] |= bcdec__bitstream_read_bits(&bstream, 4); /* gz[3:0] */ + b[1] |= bcdec__bitstream_read_bits(&bstream, 6); /* bx[5:0] */ + b[2] |= bcdec__bitstream_read_bits(&bstream, 4); /* by[3:0] */ + r[2] |= bcdec__bitstream_read_bits(&bstream, 6); /* ry[5:0] */ + r[3] |= bcdec__bitstream_read_bits(&bstream, 6); /* rz[5:0] */ + partition = bcdec__bitstream_read_bits(&bstream, 5); /* d[4:0] */ + mode = 1; + } break; + + /* mode 3 */ + case 0b00010: { + /* Partitition indices: 46 bits + Partition: 5 bits + Color Endpoints: 72 bits (11.555, 11.444, 11.444) */ + r[0] |= bcdec__bitstream_read_bits(&bstream, 10); /* rw[9:0] */ + g[0] |= bcdec__bitstream_read_bits(&bstream, 10); /* gw[9:0] */ + b[0] |= bcdec__bitstream_read_bits(&bstream, 10); /* bw[9:0] */ + r[1] |= bcdec__bitstream_read_bits(&bstream, 5); /* rx[4:0] */ + r[0] |= bcdec__bitstream_read_bit(&bstream) << 10; /* rw[10] */ + g[2] |= bcdec__bitstream_read_bits(&bstream, 4); /* gy[3:0] */ + g[1] |= bcdec__bitstream_read_bits(&bstream, 4); /* gx[3:0] */ + g[0] |= bcdec__bitstream_read_bit(&bstream) << 10; /* gw[10] */ + b[3] |= bcdec__bitstream_read_bit(&bstream); /* bz[0] */ + g[3] |= bcdec__bitstream_read_bits(&bstream, 4); /* gz[3:0] */ + b[1] |= bcdec__bitstream_read_bits(&bstream, 4); /* bx[3:0] */ + b[0] |= bcdec__bitstream_read_bit(&bstream) << 10; /* bw[10] */ + b[3] |= bcdec__bitstream_read_bit(&bstream) << 1; /* bz[1] */ + b[2] |= bcdec__bitstream_read_bits(&bstream, 4); /* by[3:0] */ + r[2] |= bcdec__bitstream_read_bits(&bstream, 5); /* ry[4:0] */ + b[3] |= bcdec__bitstream_read_bit(&bstream) << 2; /* bz[2] */ + r[3] |= bcdec__bitstream_read_bits(&bstream, 5); /* rz[4:0] */ + b[3] |= bcdec__bitstream_read_bit(&bstream) << 3; /* bz[3] */ + partition = bcdec__bitstream_read_bits(&bstream, 5); /* d[4:0] */ + mode = 2; + } break; + + /* mode 4 */ + case 0b00110: { + /* Partitition indices: 46 bits + Partition: 5 bits + Color Endpoints: 72 bits (11.444, 11.555, 11.444) */ + r[0] |= bcdec__bitstream_read_bits(&bstream, 10); /* rw[9:0] */ + g[0] |= bcdec__bitstream_read_bits(&bstream, 10); /* gw[9:0] */ + b[0] |= bcdec__bitstream_read_bits(&bstream, 10); /* bw[9:0] */ + r[1] |= bcdec__bitstream_read_bits(&bstream, 4); /* rx[3:0] */ + r[0] |= bcdec__bitstream_read_bit(&bstream) << 10; /* rw[10] */ + g[3] |= bcdec__bitstream_read_bit(&bstream) << 4; /* gz[4] */ + g[2] |= bcdec__bitstream_read_bits(&bstream, 4); /* gy[3:0] */ + g[1] |= bcdec__bitstream_read_bits(&bstream, 5); /* gx[4:0] */ + g[0] |= bcdec__bitstream_read_bit(&bstream) << 10; /* gw[10] */ + g[3] |= bcdec__bitstream_read_bits(&bstream, 4); /* gz[3:0] */ + b[1] |= bcdec__bitstream_read_bits(&bstream, 4); /* bx[3:0] */ + b[0] |= bcdec__bitstream_read_bit(&bstream) << 10; /* bw[10] */ + b[3] |= bcdec__bitstream_read_bit(&bstream) << 1; /* bz[1] */ + b[2] |= bcdec__bitstream_read_bits(&bstream, 4); /* by[3:0] */ + r[2] |= bcdec__bitstream_read_bits(&bstream, 4); /* ry[3:0] */ + b[3] |= bcdec__bitstream_read_bit(&bstream); /* bz[0] */ + b[3] |= bcdec__bitstream_read_bit(&bstream) << 2; /* bz[2] */ + r[3] |= bcdec__bitstream_read_bits(&bstream, 4); /* rz[3:0] */ + g[2] |= bcdec__bitstream_read_bit(&bstream) << 4; /* gy[4] */ + b[3] |= bcdec__bitstream_read_bit(&bstream) << 3; /* bz[3] */ + partition = bcdec__bitstream_read_bits(&bstream, 5); /* d[4:0] */ + mode = 3; + } break; + + /* mode 5 */ + case 0b01010: { + /* Partitition indices: 46 bits + Partition: 5 bits + Color Endpoints: 72 bits (11.444, 11.444, 11.555) */ + r[0] |= bcdec__bitstream_read_bits(&bstream, 10); /* rw[9:0] */ + g[0] |= bcdec__bitstream_read_bits(&bstream, 10); /* gw[9:0] */ + b[0] |= bcdec__bitstream_read_bits(&bstream, 10); /* bw[9:0] */ + r[1] |= bcdec__bitstream_read_bits(&bstream, 4); /* rx[3:0] */ + r[0] |= bcdec__bitstream_read_bit(&bstream) << 10; /* rw[10] */ + b[2] |= bcdec__bitstream_read_bit(&bstream) << 4; /* by[4] */ + g[2] |= bcdec__bitstream_read_bits(&bstream, 4); /* gy[3:0] */ + g[1] |= bcdec__bitstream_read_bits(&bstream, 4); /* gx[3:0] */ + g[0] |= bcdec__bitstream_read_bit(&bstream) << 10; /* gw[10] */ + b[3] |= bcdec__bitstream_read_bit(&bstream); /* bz[0] */ + g[3] |= bcdec__bitstream_read_bits(&bstream, 4); /* gz[3:0] */ + b[1] |= bcdec__bitstream_read_bits(&bstream, 5); /* bx[4:0] */ + b[0] |= bcdec__bitstream_read_bit(&bstream) << 10; /* bw[10] */ + b[2] |= bcdec__bitstream_read_bits(&bstream, 4); /* by[3:0] */ + r[2] |= bcdec__bitstream_read_bits(&bstream, 4); /* ry[3:0] */ + b[3] |= bcdec__bitstream_read_bit(&bstream) << 1; /* bz[1] */ + b[3] |= bcdec__bitstream_read_bit(&bstream) << 2; /* bz[2] */ + r[3] |= bcdec__bitstream_read_bits(&bstream, 4); /* rz[3:0] */ + b[3] |= bcdec__bitstream_read_bit(&bstream) << 4; /* bz[4] */ + b[3] |= bcdec__bitstream_read_bit(&bstream) << 3; /* bz[3] */ + partition = bcdec__bitstream_read_bits(&bstream, 5); /* d[4:0] */ + mode = 4; + } break; + + /* mode 6 */ + case 0b01110: { + /* Partitition indices: 46 bits + Partition: 5 bits + Color Endpoints: 72 bits (9555, 9555, 9555) */ + r[0] |= bcdec__bitstream_read_bits(&bstream, 9); /* rw[8:0] */ + b[2] |= bcdec__bitstream_read_bit(&bstream) << 4; /* by[4] */ + g[0] |= bcdec__bitstream_read_bits(&bstream, 9); /* gw[8:0] */ + g[2] |= bcdec__bitstream_read_bit(&bstream) << 4; /* gy[4] */ + b[0] |= bcdec__bitstream_read_bits(&bstream, 9); /* bw[8:0] */ + b[3] |= bcdec__bitstream_read_bit(&bstream) << 4; /* bz[4] */ + r[1] |= bcdec__bitstream_read_bits(&bstream, 5); /* rx[4:0] */ + g[3] |= bcdec__bitstream_read_bit(&bstream) << 4; /* gz[4] */ + g[2] |= bcdec__bitstream_read_bits(&bstream, 4); /* gy[3:0] */ + g[1] |= bcdec__bitstream_read_bits(&bstream, 5); /* gx[4:0] */ + b[3] |= bcdec__bitstream_read_bit(&bstream); /* bz[0] */ + g[3] |= bcdec__bitstream_read_bits(&bstream, 4); /* gx[3:0] */ + b[1] |= bcdec__bitstream_read_bits(&bstream, 5); /* bx[4:0] */ + b[3] |= bcdec__bitstream_read_bit(&bstream) << 1; /* bz[1] */ + b[2] |= bcdec__bitstream_read_bits(&bstream, 4); /* by[3:0] */ + r[2] |= bcdec__bitstream_read_bits(&bstream, 5); /* ry[4:0] */ + b[3] |= bcdec__bitstream_read_bit(&bstream) << 2; /* bz[2] */ + r[3] |= bcdec__bitstream_read_bits(&bstream, 5); /* rz[4:0] */ + b[3] |= bcdec__bitstream_read_bit(&bstream) << 3; /* bz[3] */ + partition = bcdec__bitstream_read_bits(&bstream, 5); /* d[4:0] */ + mode = 5; + } break; + + /* mode 7 */ + case 0b10010: { + /* Partitition indices: 46 bits + Partition: 5 bits + Color Endpoints: 72 bits (8666, 8555, 8555) */ + r[0] |= bcdec__bitstream_read_bits(&bstream, 8); /* rw[7:0] */ + g[3] |= bcdec__bitstream_read_bit(&bstream) << 4; /* gz[4] */ + b[2] |= bcdec__bitstream_read_bit(&bstream) << 4; /* by[4] */ + g[0] |= bcdec__bitstream_read_bits(&bstream, 8); /* gw[7:0] */ + b[3] |= bcdec__bitstream_read_bit(&bstream) << 2; /* bz[2] */ + g[2] |= bcdec__bitstream_read_bit(&bstream) << 4; /* gy[4] */ + b[0] |= bcdec__bitstream_read_bits(&bstream, 8); /* bw[7:0] */ + b[3] |= bcdec__bitstream_read_bit(&bstream) << 3; /* bz[3] */ + b[3] |= bcdec__bitstream_read_bit(&bstream) << 4; /* bz[4] */ + r[1] |= bcdec__bitstream_read_bits(&bstream, 6); /* rx[5:0] */ + g[2] |= bcdec__bitstream_read_bits(&bstream, 4); /* gy[3:0] */ + g[1] |= bcdec__bitstream_read_bits(&bstream, 5); /* gx[4:0] */ + b[3] |= bcdec__bitstream_read_bit(&bstream); /* bz[0] */ + g[3] |= bcdec__bitstream_read_bits(&bstream, 4); /* gz[3:0] */ + b[1] |= bcdec__bitstream_read_bits(&bstream, 5); /* bx[4:0] */ + b[3] |= bcdec__bitstream_read_bit(&bstream) << 1; /* bz[1] */ + b[2] |= bcdec__bitstream_read_bits(&bstream, 4); /* by[3:0] */ + r[2] |= bcdec__bitstream_read_bits(&bstream, 6); /* ry[5:0] */ + r[3] |= bcdec__bitstream_read_bits(&bstream, 6); /* rz[5:0] */ + partition = bcdec__bitstream_read_bits(&bstream, 5); /* d[4:0] */ + mode = 6; + } break; + + /* mode 8 */ + case 0b10110: { + /* Partitition indices: 46 bits + Partition: 5 bits + Color Endpoints: 72 bits (8555, 8666, 8555) */ + r[0] |= bcdec__bitstream_read_bits(&bstream, 8); /* rw[7:0] */ + b[3] |= bcdec__bitstream_read_bit(&bstream); /* bz[0] */ + b[2] |= bcdec__bitstream_read_bit(&bstream) << 4; /* by[4] */ + g[0] |= bcdec__bitstream_read_bits(&bstream, 8); /* gw[7:0] */ + g[2] |= bcdec__bitstream_read_bit(&bstream) << 5; /* gy[5] */ + g[2] |= bcdec__bitstream_read_bit(&bstream) << 4; /* gy[4] */ + b[0] |= bcdec__bitstream_read_bits(&bstream, 8); /* bw[7:0] */ + g[3] |= bcdec__bitstream_read_bit(&bstream) << 5; /* gz[5] */ + b[3] |= bcdec__bitstream_read_bit(&bstream) << 4; /* bz[4] */ + r[1] |= bcdec__bitstream_read_bits(&bstream, 5); /* rx[4:0] */ + g[3] |= bcdec__bitstream_read_bit(&bstream) << 4; /* gz[4] */ + g[2] |= bcdec__bitstream_read_bits(&bstream, 4); /* gy[3:0] */ + g[1] |= bcdec__bitstream_read_bits(&bstream, 6); /* gx[5:0] */ + g[3] |= bcdec__bitstream_read_bits(&bstream, 4); /* zx[3:0] */ + b[1] |= bcdec__bitstream_read_bits(&bstream, 5); /* bx[4:0] */ + b[3] |= bcdec__bitstream_read_bit(&bstream) << 1; /* bz[1] */ + b[2] |= bcdec__bitstream_read_bits(&bstream, 4); /* by[3:0] */ + r[2] |= bcdec__bitstream_read_bits(&bstream, 5); /* ry[4:0] */ + b[3] |= bcdec__bitstream_read_bit(&bstream) << 2; /* bz[2] */ + r[3] |= bcdec__bitstream_read_bits(&bstream, 5); /* rz[4:0] */ + b[3] |= bcdec__bitstream_read_bit(&bstream) << 3; /* bz[3] */ + partition = bcdec__bitstream_read_bits(&bstream, 5); /* d[4:0] */ + mode = 7; + } break; + + /* mode 9 */ + case 0b11010: { + /* Partitition indices: 46 bits + Partition: 5 bits + Color Endpoints: 72 bits (8555, 8555, 8666) */ + r[0] |= bcdec__bitstream_read_bits(&bstream, 8); /* rw[7:0] */ + b[3] |= bcdec__bitstream_read_bit(&bstream) << 1; /* bz[1] */ + b[2] |= bcdec__bitstream_read_bit(&bstream) << 4; /* by[4] */ + g[0] |= bcdec__bitstream_read_bits(&bstream, 8); /* gw[7:0] */ + b[2] |= bcdec__bitstream_read_bit(&bstream) << 5; /* by[5] */ + g[2] |= bcdec__bitstream_read_bit(&bstream) << 4; /* gy[4] */ + b[0] |= bcdec__bitstream_read_bits(&bstream, 8); /* bw[7:0] */ + b[3] |= bcdec__bitstream_read_bit(&bstream) << 5; /* bz[5] */ + b[3] |= bcdec__bitstream_read_bit(&bstream) << 4; /* bz[4] */ + r[1] |= bcdec__bitstream_read_bits(&bstream, 5); /* bw[4:0] */ + g[3] |= bcdec__bitstream_read_bit(&bstream) << 4; /* gz[4] */ + g[2] |= bcdec__bitstream_read_bits(&bstream, 4); /* gy[3:0] */ + g[1] |= bcdec__bitstream_read_bits(&bstream, 5); /* gx[4:0] */ + b[3] |= bcdec__bitstream_read_bit(&bstream); /* bz[0] */ + g[3] |= bcdec__bitstream_read_bits(&bstream, 4); /* gz[3:0] */ + b[1] |= bcdec__bitstream_read_bits(&bstream, 6); /* bx[5:0] */ + b[2] |= bcdec__bitstream_read_bits(&bstream, 4); /* by[3:0] */ + r[2] |= bcdec__bitstream_read_bits(&bstream, 5); /* ry[4:0] */ + b[3] |= bcdec__bitstream_read_bit(&bstream) << 2; /* bz[2] */ + r[3] |= bcdec__bitstream_read_bits(&bstream, 5); /* rz[4:0] */ + b[3] |= bcdec__bitstream_read_bit(&bstream) << 3; /* bz[3] */ + partition = bcdec__bitstream_read_bits(&bstream, 5); /* d[4:0] */ + mode = 8; + } break; + + /* mode 10 */ + case 0b11110: { + /* Partitition indices: 46 bits + Partition: 5 bits + Color Endpoints: 72 bits (6666, 6666, 6666) */ + r[0] |= bcdec__bitstream_read_bits(&bstream, 6); /* rw[5:0] */ + g[3] |= bcdec__bitstream_read_bit(&bstream) << 4; /* gz[4] */ + b[3] |= bcdec__bitstream_read_bit(&bstream); /* bz[0] */ + b[3] |= bcdec__bitstream_read_bit(&bstream) << 1; /* bz[1] */ + b[2] |= bcdec__bitstream_read_bit(&bstream) << 4; /* by[4] */ + g[0] |= bcdec__bitstream_read_bits(&bstream, 6); /* gw[5:0] */ + g[2] |= bcdec__bitstream_read_bit(&bstream) << 5; /* gy[5] */ + b[2] |= bcdec__bitstream_read_bit(&bstream) << 5; /* by[5] */ + b[3] |= bcdec__bitstream_read_bit(&bstream) << 2; /* bz[2] */ + g[2] |= bcdec__bitstream_read_bit(&bstream) << 4; /* gy[4] */ + b[0] |= bcdec__bitstream_read_bits(&bstream, 6); /* bw[5:0] */ + g[3] |= bcdec__bitstream_read_bit(&bstream) << 5; /* gz[5] */ + b[3] |= bcdec__bitstream_read_bit(&bstream) << 3; /* bz[3] */ + b[3] |= bcdec__bitstream_read_bit(&bstream) << 5; /* bz[5] */ + b[3] |= bcdec__bitstream_read_bit(&bstream) << 4; /* bz[4] */ + r[1] |= bcdec__bitstream_read_bits(&bstream, 6); /* rx[5:0] */ + g[2] |= bcdec__bitstream_read_bits(&bstream, 4); /* gy[3:0] */ + g[1] |= bcdec__bitstream_read_bits(&bstream, 6); /* gx[5:0] */ + g[3] |= bcdec__bitstream_read_bits(&bstream, 4); /* gz[3:0] */ + b[1] |= bcdec__bitstream_read_bits(&bstream, 6); /* bx[5:0] */ + b[2] |= bcdec__bitstream_read_bits(&bstream, 4); /* by[3:0] */ + r[2] |= bcdec__bitstream_read_bits(&bstream, 6); /* ry[5:0] */ + r[3] |= bcdec__bitstream_read_bits(&bstream, 6); /* rz[5:0] */ + partition = bcdec__bitstream_read_bits(&bstream, 5); /* d[4:0] */ + mode = 9; + } break; + + /* mode 11 */ + case 0b00011: { + /* Partitition indices: 63 bits + Partition: 0 bits + Color Endpoints: 60 bits (10.10, 10.10, 10.10) */ + r[0] |= bcdec__bitstream_read_bits(&bstream, 10); /* rw[9:0] */ + g[0] |= bcdec__bitstream_read_bits(&bstream, 10); /* gw[9:0] */ + b[0] |= bcdec__bitstream_read_bits(&bstream, 10); /* bw[9:0] */ + r[1] |= bcdec__bitstream_read_bits(&bstream, 10); /* rx[9:0] */ + g[1] |= bcdec__bitstream_read_bits(&bstream, 10); /* gx[9:0] */ + b[1] |= bcdec__bitstream_read_bits(&bstream, 10); /* bx[9:0] */ + mode = 10; + } break; + + /* mode 12 */ + case 0b00111: { + /* Partitition indices: 63 bits + Partition: 0 bits + Color Endpoints: 60 bits (11.9, 11.9, 11.9) */ + r[0] |= bcdec__bitstream_read_bits(&bstream, 10); /* rw[9:0] */ + g[0] |= bcdec__bitstream_read_bits(&bstream, 10); /* gw[9:0] */ + b[0] |= bcdec__bitstream_read_bits(&bstream, 10); /* bw[9:0] */ + r[1] |= bcdec__bitstream_read_bits(&bstream, 9); /* rx[8:0] */ + r[0] |= bcdec__bitstream_read_bit(&bstream) << 10; /* rw[10] */ + g[1] |= bcdec__bitstream_read_bits(&bstream, 9); /* gx[8:0] */ + g[0] |= bcdec__bitstream_read_bit(&bstream) << 10; /* gw[10] */ + b[1] |= bcdec__bitstream_read_bits(&bstream, 9); /* bx[8:0] */ + b[0] |= bcdec__bitstream_read_bit(&bstream) << 10; /* bw[10] */ + mode = 11; + } break; + + /* mode 13 */ + case 0b01011: { + /* Partitition indices: 63 bits + Partition: 0 bits + Color Endpoints: 60 bits (12.8, 12.8, 12.8) */ + r[0] |= bcdec__bitstream_read_bits(&bstream, 10); /* rw[9:0] */ + g[0] |= bcdec__bitstream_read_bits(&bstream, 10); /* gw[9:0] */ + b[0] |= bcdec__bitstream_read_bits(&bstream, 10); /* bw[9:0] */ + r[1] |= bcdec__bitstream_read_bits(&bstream, 8); /* rx[7:0] */ + r[0] |= bcdec__bitstream_read_bits_r(&bstream, 2) << 10;/* rx[10:11] */ + g[1] |= bcdec__bitstream_read_bits(&bstream, 8); /* gx[7:0] */ + g[0] |= bcdec__bitstream_read_bits_r(&bstream, 2) << 10;/* gx[10:11] */ + b[1] |= bcdec__bitstream_read_bits(&bstream, 8); /* bx[7:0] */ + b[0] |= bcdec__bitstream_read_bits_r(&bstream, 2) << 10;/* bx[10:11] */ + mode = 12; + } break; + + /* mode 14 */ + case 0b01111: { + /* Partitition indices: 63 bits + Partition: 0 bits + Color Endpoints: 60 bits (16.4, 16.4, 16.4) */ + r[0] |= bcdec__bitstream_read_bits(&bstream, 10); /* rw[9:0] */ + g[0] |= bcdec__bitstream_read_bits(&bstream, 10); /* gw[9:0] */ + b[0] |= bcdec__bitstream_read_bits(&bstream, 10); /* bw[9:0] */ + r[1] |= bcdec__bitstream_read_bits(&bstream, 4); /* rx[3:0] */ + r[0] |= bcdec__bitstream_read_bits_r(&bstream, 6) << 10;/* rw[10:15] */ + g[1] |= bcdec__bitstream_read_bits(&bstream, 4); /* gx[3:0] */ + g[0] |= bcdec__bitstream_read_bits_r(&bstream, 6) << 10;/* gw[10:15] */ + b[1] |= bcdec__bitstream_read_bits(&bstream, 4); /* bx[3:0] */ + b[0] |= bcdec__bitstream_read_bits_r(&bstream, 6) << 10;/* bw[10:15] */ + mode = 13; + } break; + + default: { + /* Modes 10011, 10111, 11011, and 11111 (not shown) are reserved. + Do not use these in your encoder. If the hardware is passed blocks + with one of these modes specified, the resulting decompressed block + must contain all zeroes in all channels except for the alpha channel. */ + for (i = 0; i < 4; ++i) { + for (j = 0; j < 4; ++j) { + decompressed[j * 3 + 0] = 0; + decompressed[j * 3 + 1] = 0; + decompressed[j * 3 + 2] = 0; + } + decompressed += destinationPitch; + } + + return; + } + } + + numPartitions = (mode >= 10) ? 0 : 1; + + actualBits0Mode = actual_bits_count[0][mode]; + if (isSigned) { + r[0] = bcdec__extend_sign(r[0], actualBits0Mode); + g[0] = bcdec__extend_sign(g[0], actualBits0Mode); + b[0] = bcdec__extend_sign(b[0], actualBits0Mode); + } + + /* Mode 11 (like Mode 10) does not use delta compression, + and instead stores both color endpoints explicitly. */ + if ((mode != 9 && mode != 10) || isSigned) { + for (i = 1; i < (numPartitions + 1) * 2; ++i) { + r[i] = bcdec__extend_sign(r[i], actual_bits_count[1][mode]); + g[i] = bcdec__extend_sign(g[i], actual_bits_count[2][mode]); + b[i] = bcdec__extend_sign(b[i], actual_bits_count[3][mode]); + } + } + + if (mode != 9 && mode != 10) { + for (i = 1; i < (numPartitions + 1) * 2; ++i) { + r[i] = bcdec__transform_inverse(r[i], r[0], actualBits0Mode, isSigned); + g[i] = bcdec__transform_inverse(g[i], g[0], actualBits0Mode, isSigned); + b[i] = bcdec__transform_inverse(b[i], b[0], actualBits0Mode, isSigned); + } + } + + for (i = 0; i < (numPartitions + 1) * 2; ++i) { + r[i] = bcdec__unquantize(r[i], actualBits0Mode, isSigned); + g[i] = bcdec__unquantize(g[i], actualBits0Mode, isSigned); + b[i] = bcdec__unquantize(b[i], actualBits0Mode, isSigned); + } + + weights = (mode >= 10) ? aWeight4 : aWeight3; + for (i = 0; i < 4; ++i) { + for (j = 0; j < 4; ++j) { + partitionSet = (mode >= 10) ? ((i|j) ? 0 : 128) : partition_sets[partition][i][j]; + + indexBits = (mode >= 10) ? 4 : 3; + /* fix-up index is specified with one less bit */ + /* The fix-up index for subset 0 is always index 0 */ + if (partitionSet & 0x80) { + indexBits--; + } + partitionSet &= 0x01; + + index = bcdec__bitstream_read_bits(&bstream, indexBits); + + ep_i = partitionSet * 2; + decompressed[j * 3 + 0] = bcdec__finish_unquantize( + bcdec__interpolate(r[ep_i], r[ep_i+1], weights, index), isSigned); + decompressed[j * 3 + 1] = bcdec__finish_unquantize( + bcdec__interpolate(g[ep_i], g[ep_i+1], weights, index), isSigned); + decompressed[j * 3 + 2] = bcdec__finish_unquantize( + bcdec__interpolate(b[ep_i], b[ep_i+1], weights, index), isSigned); + } + + decompressed += destinationPitch; + } +} + +BCDECDEF void bcdec_bc6h_float(const void* compressedBlock, void* decompressedBlock, int destinationPitch, int isSigned) { + unsigned short block[16*3]; + float* decompressed; + const unsigned short* b; + int i, j; + + bcdec_bc6h_half(compressedBlock, block, 4*3, isSigned); + b = block; + decompressed = (float*)decompressedBlock; + for (i = 0; i < 4; ++i) { + for (j = 0; j < 4; ++j) { + decompressed[j * 3 + 0] = bcdec__half_to_float_quick(*b++); + decompressed[j * 3 + 1] = bcdec__half_to_float_quick(*b++); + decompressed[j * 3 + 2] = bcdec__half_to_float_quick(*b++); + } + decompressed += destinationPitch; + } +} + +static void bcdec__swap_values(int* a, int* b) { + a[0] ^= b[0], b[0] ^= a[0], a[0] ^= b[0]; +} + +BCDECDEF void bcdec_bc7(const void* compressedBlock, void* decompressedBlock, int destinationPitch) { + static char actual_bits_count[2][8] = { + { 4, 6, 5, 7, 5, 7, 7, 5 }, /* RGBA */ + { 0, 0, 0, 0, 6, 8, 7, 5 }, /* Alpha */ + }; + + /* There are 64 possible partition sets for a two-region tile. + Each 4x4 block represents a single shape. + Here also every fix-up index has MSB bit set. */ + static unsigned char partition_sets[2][64][4][4] = { + { /* Partition table for 2-subset BPTC */ + { {128, 0, 1, 1}, {0, 0, 1, 1}, { 0, 0, 1, 1}, {0, 0, 1, 129} }, /* 0 */ + { {128, 0, 0, 1}, {0, 0, 0, 1}, { 0, 0, 0, 1}, {0, 0, 0, 129} }, /* 1 */ + { {128, 1, 1, 1}, {0, 1, 1, 1}, { 0, 1, 1, 1}, {0, 1, 1, 129} }, /* 2 */ + { {128, 0, 0, 1}, {0, 0, 1, 1}, { 0, 0, 1, 1}, {0, 1, 1, 129} }, /* 3 */ + { {128, 0, 0, 0}, {0, 0, 0, 1}, { 0, 0, 0, 1}, {0, 0, 1, 129} }, /* 4 */ + { {128, 0, 1, 1}, {0, 1, 1, 1}, { 0, 1, 1, 1}, {1, 1, 1, 129} }, /* 5 */ + { {128, 0, 0, 1}, {0, 0, 1, 1}, { 0, 1, 1, 1}, {1, 1, 1, 129} }, /* 6 */ + { {128, 0, 0, 0}, {0, 0, 0, 1}, { 0, 0, 1, 1}, {0, 1, 1, 129} }, /* 7 */ + { {128, 0, 0, 0}, {0, 0, 0, 0}, { 0, 0, 0, 1}, {0, 0, 1, 129} }, /* 8 */ + { {128, 0, 1, 1}, {0, 1, 1, 1}, { 1, 1, 1, 1}, {1, 1, 1, 129} }, /* 9 */ + { {128, 0, 0, 0}, {0, 0, 0, 1}, { 0, 1, 1, 1}, {1, 1, 1, 129} }, /* 10 */ + { {128, 0, 0, 0}, {0, 0, 0, 0}, { 0, 0, 0, 1}, {0, 1, 1, 129} }, /* 11 */ + { {128, 0, 0, 1}, {0, 1, 1, 1}, { 1, 1, 1, 1}, {1, 1, 1, 129} }, /* 12 */ + { {128, 0, 0, 0}, {0, 0, 0, 0}, { 1, 1, 1, 1}, {1, 1, 1, 129} }, /* 13 */ + { {128, 0, 0, 0}, {1, 1, 1, 1}, { 1, 1, 1, 1}, {1, 1, 1, 129} }, /* 14 */ + { {128, 0, 0, 0}, {0, 0, 0, 0}, { 0, 0, 0, 0}, {1, 1, 1, 129} }, /* 15 */ + { {128, 0, 0, 0}, {1, 0, 0, 0}, { 1, 1, 1, 0}, {1, 1, 1, 129} }, /* 16 */ + { {128, 1, 129, 1}, {0, 0, 0, 1}, { 0, 0, 0, 0}, {0, 0, 0, 0} }, /* 17 */ + { {128, 0, 0, 0}, {0, 0, 0, 0}, {129, 0, 0, 0}, {1, 1, 1, 0} }, /* 18 */ + { {128, 1, 129, 1}, {0, 0, 1, 1}, { 0, 0, 0, 1}, {0, 0, 0, 0} }, /* 19 */ + { {128, 0, 129, 1}, {0, 0, 0, 1}, { 0, 0, 0, 0}, {0, 0, 0, 0} }, /* 20 */ + { {128, 0, 0, 0}, {1, 0, 0, 0}, {129, 1, 0, 0}, {1, 1, 1, 0} }, /* 21 */ + { {128, 0, 0, 0}, {0, 0, 0, 0}, {129, 0, 0, 0}, {1, 1, 0, 0} }, /* 22 */ + { {128, 1, 1, 1}, {0, 0, 1, 1}, { 0, 0, 1, 1}, {0, 0, 0, 129} }, /* 23 */ + { {128, 0, 129, 1}, {0, 0, 0, 1}, { 0, 0, 0, 1}, {0, 0, 0, 0} }, /* 24 */ + { {128, 0, 0, 0}, {1, 0, 0, 0}, {129, 0, 0, 0}, {1, 1, 0, 0} }, /* 25 */ + { {128, 1, 129, 0}, {0, 1, 1, 0}, { 0, 1, 1, 0}, {0, 1, 1, 0} }, /* 26 */ + { {128, 0, 129, 1}, {0, 1, 1, 0}, { 0, 1, 1, 0}, {1, 1, 0, 0} }, /* 27 */ + { {128, 0, 0, 1}, {0, 1, 1, 1}, {129, 1, 1, 0}, {1, 0, 0, 0} }, /* 28 */ + { {128, 0, 0, 0}, {1, 1, 1, 1}, {129, 1, 1, 1}, {0, 0, 0, 0} }, /* 29 */ + { {128, 1, 129, 1}, {0, 0, 0, 1}, { 1, 0, 0, 0}, {1, 1, 1, 0} }, /* 30 */ + { {128, 0, 129, 1}, {1, 0, 0, 1}, { 1, 0, 0, 1}, {1, 1, 0, 0} }, /* 31 */ + { {128, 1, 0, 1}, {0, 1, 0, 1}, { 0, 1, 0, 1}, {0, 1, 0, 129} }, /* 32 */ + { {128, 0, 0, 0}, {1, 1, 1, 1}, { 0, 0, 0, 0}, {1, 1, 1, 129} }, /* 33 */ + { {128, 1, 0, 1}, {1, 0, 129, 0}, { 0, 1, 0, 1}, {1, 0, 1, 0} }, /* 34 */ + { {128, 0, 1, 1}, {0, 0, 1, 1}, {129, 1, 0, 0}, {1, 1, 0, 0} }, /* 35 */ + { {128, 0, 129, 1}, {1, 1, 0, 0}, { 0, 0, 1, 1}, {1, 1, 0, 0} }, /* 36 */ + { {128, 1, 0, 1}, {0, 1, 0, 1}, {129, 0, 1, 0}, {1, 0, 1, 0} }, /* 37 */ + { {128, 1, 1, 0}, {1, 0, 0, 1}, { 0, 1, 1, 0}, {1, 0, 0, 129} }, /* 38 */ + { {128, 1, 0, 1}, {1, 0, 1, 0}, { 1, 0, 1, 0}, {0, 1, 0, 129} }, /* 39 */ + { {128, 1, 129, 1}, {0, 0, 1, 1}, { 1, 1, 0, 0}, {1, 1, 1, 0} }, /* 40 */ + { {128, 0, 0, 1}, {0, 0, 1, 1}, {129, 1, 0, 0}, {1, 0, 0, 0} }, /* 41 */ + { {128, 0, 129, 1}, {0, 0, 1, 0}, { 0, 1, 0, 0}, {1, 1, 0, 0} }, /* 42 */ + { {128, 0, 129, 1}, {1, 0, 1, 1}, { 1, 1, 0, 1}, {1, 1, 0, 0} }, /* 43 */ + { {128, 1, 129, 0}, {1, 0, 0, 1}, { 1, 0, 0, 1}, {0, 1, 1, 0} }, /* 44 */ + { {128, 0, 1, 1}, {1, 1, 0, 0}, { 1, 1, 0, 0}, {0, 0, 1, 129} }, /* 45 */ + { {128, 1, 1, 0}, {0, 1, 1, 0}, { 1, 0, 0, 1}, {1, 0, 0, 129} }, /* 46 */ + { {128, 0, 0, 0}, {0, 1, 129, 0}, { 0, 1, 1, 0}, {0, 0, 0, 0} }, /* 47 */ + { {128, 1, 0, 0}, {1, 1, 129, 0}, { 0, 1, 0, 0}, {0, 0, 0, 0} }, /* 48 */ + { {128, 0, 129, 0}, {0, 1, 1, 1}, { 0, 0, 1, 0}, {0, 0, 0, 0} }, /* 49 */ + { {128, 0, 0, 0}, {0, 0, 129, 0}, { 0, 1, 1, 1}, {0, 0, 1, 0} }, /* 50 */ + { {128, 0, 0, 0}, {0, 1, 0, 0}, {129, 1, 1, 0}, {0, 1, 0, 0} }, /* 51 */ + { {128, 1, 1, 0}, {1, 1, 0, 0}, { 1, 0, 0, 1}, {0, 0, 1, 129} }, /* 52 */ + { {128, 0, 1, 1}, {0, 1, 1, 0}, { 1, 1, 0, 0}, {1, 0, 0, 129} }, /* 53 */ + { {128, 1, 129, 0}, {0, 0, 1, 1}, { 1, 0, 0, 1}, {1, 1, 0, 0} }, /* 54 */ + { {128, 0, 129, 1}, {1, 0, 0, 1}, { 1, 1, 0, 0}, {0, 1, 1, 0} }, /* 55 */ + { {128, 1, 1, 0}, {1, 1, 0, 0}, { 1, 1, 0, 0}, {1, 0, 0, 129} }, /* 56 */ + { {128, 1, 1, 0}, {0, 0, 1, 1}, { 0, 0, 1, 1}, {1, 0, 0, 129} }, /* 57 */ + { {128, 1, 1, 1}, {1, 1, 1, 0}, { 1, 0, 0, 0}, {0, 0, 0, 129} }, /* 58 */ + { {128, 0, 0, 1}, {1, 0, 0, 0}, { 1, 1, 1, 0}, {0, 1, 1, 129} }, /* 59 */ + { {128, 0, 0, 0}, {1, 1, 1, 1}, { 0, 0, 1, 1}, {0, 0, 1, 129} }, /* 60 */ + { {128, 0, 129, 1}, {0, 0, 1, 1}, { 1, 1, 1, 1}, {0, 0, 0, 0} }, /* 61 */ + { {128, 0, 129, 0}, {0, 0, 1, 0}, { 1, 1, 1, 0}, {1, 1, 1, 0} }, /* 62 */ + { {128, 1, 0, 0}, {0, 1, 0, 0}, { 0, 1, 1, 1}, {0, 1, 1, 129} } /* 63 */ + }, + { /* Partition table for 3-subset BPTC */ + { {128, 0, 1, 129}, {0, 0, 1, 1}, { 0, 2, 2, 1}, { 2, 2, 2, 130} }, /* 0 */ + { {128, 0, 0, 129}, {0, 0, 1, 1}, {130, 2, 1, 1}, { 2, 2, 2, 1} }, /* 1 */ + { {128, 0, 0, 0}, {2, 0, 0, 1}, {130, 2, 1, 1}, { 2, 2, 1, 129} }, /* 2 */ + { {128, 2, 2, 130}, {0, 0, 2, 2}, { 0, 0, 1, 1}, { 0, 1, 1, 129} }, /* 3 */ + { {128, 0, 0, 0}, {0, 0, 0, 0}, {129, 1, 2, 2}, { 1, 1, 2, 130} }, /* 4 */ + { {128, 0, 1, 129}, {0, 0, 1, 1}, { 0, 0, 2, 2}, { 0, 0, 2, 130} }, /* 5 */ + { {128, 0, 2, 130}, {0, 0, 2, 2}, { 1, 1, 1, 1}, { 1, 1, 1, 129} }, /* 6 */ + { {128, 0, 1, 1}, {0, 0, 1, 1}, {130, 2, 1, 1}, { 2, 2, 1, 129} }, /* 7 */ + { {128, 0, 0, 0}, {0, 0, 0, 0}, {129, 1, 1, 1}, { 2, 2, 2, 130} }, /* 8 */ + { {128, 0, 0, 0}, {1, 1, 1, 1}, {129, 1, 1, 1}, { 2, 2, 2, 130} }, /* 9 */ + { {128, 0, 0, 0}, {1, 1, 129, 1}, { 2, 2, 2, 2}, { 2, 2, 2, 130} }, /* 10 */ + { {128, 0, 1, 2}, {0, 0, 129, 2}, { 0, 0, 1, 2}, { 0, 0, 1, 130} }, /* 11 */ + { {128, 1, 1, 2}, {0, 1, 129, 2}, { 0, 1, 1, 2}, { 0, 1, 1, 130} }, /* 12 */ + { {128, 1, 2, 2}, {0, 129, 2, 2}, { 0, 1, 2, 2}, { 0, 1, 2, 130} }, /* 13 */ + { {128, 0, 1, 129}, {0, 1, 1, 2}, { 1, 1, 2, 2}, { 1, 2, 2, 130} }, /* 14 */ + { {128, 0, 1, 129}, {2, 0, 0, 1}, {130, 2, 0, 0}, { 2, 2, 2, 0} }, /* 15 */ + { {128, 0, 0, 129}, {0, 0, 1, 1}, { 0, 1, 1, 2}, { 1, 1, 2, 130} }, /* 16 */ + { {128, 1, 1, 129}, {0, 0, 1, 1}, {130, 0, 0, 1}, { 2, 2, 0, 0} }, /* 17 */ + { {128, 0, 0, 0}, {1, 1, 2, 2}, {129, 1, 2, 2}, { 1, 1, 2, 130} }, /* 18 */ + { {128, 0, 2, 130}, {0, 0, 2, 2}, { 0, 0, 2, 2}, { 1, 1, 1, 129} }, /* 19 */ + { {128, 1, 1, 129}, {0, 1, 1, 1}, { 0, 2, 2, 2}, { 0, 2, 2, 130} }, /* 20 */ + { {128, 0, 0, 129}, {0, 0, 0, 1}, {130, 2, 2, 1}, { 2, 2, 2, 1} }, /* 21 */ + { {128, 0, 0, 0}, {0, 0, 129, 1}, { 0, 1, 2, 2}, { 0, 1, 2, 130} }, /* 22 */ + { {128, 0, 0, 0}, {1, 1, 0, 0}, {130, 2, 129, 0}, { 2, 2, 1, 0} }, /* 23 */ + { {128, 1, 2, 130}, {0, 129, 2, 2}, { 0, 0, 1, 1}, { 0, 0, 0, 0} }, /* 24 */ + { {128, 0, 1, 2}, {0, 0, 1, 2}, {129, 1, 2, 2}, { 2, 2, 2, 130} }, /* 25 */ + { {128, 1, 1, 0}, {1, 2, 130, 1}, {129, 2, 2, 1}, { 0, 1, 1, 0} }, /* 26 */ + { {128, 0, 0, 0}, {0, 1, 129, 0}, { 1, 2, 130, 1}, { 1, 2, 2, 1} }, /* 27 */ + { {128, 0, 2, 2}, {1, 1, 0, 2}, {129, 1, 0, 2}, { 0, 0, 2, 130} }, /* 28 */ + { {128, 1, 1, 0}, {0, 129, 1, 0}, { 2, 0, 0, 2}, { 2, 2, 2, 130} }, /* 29 */ + { {128, 0, 1, 1}, {0, 1, 2, 2}, { 0, 1, 130, 2}, { 0, 0, 1, 129} }, /* 30 */ + { {128, 0, 0, 0}, {2, 0, 0, 0}, {130, 2, 1, 1}, { 2, 2, 2, 129} }, /* 31 */ + { {128, 0, 0, 0}, {0, 0, 0, 2}, {129, 1, 2, 2}, { 1, 2, 2, 130} }, /* 32 */ + { {128, 2, 2, 130}, {0, 0, 2, 2}, { 0, 0, 1, 2}, { 0, 0, 1, 129} }, /* 33 */ + { {128, 0, 1, 129}, {0, 0, 1, 2}, { 0, 0, 2, 2}, { 0, 2, 2, 130} }, /* 34 */ + { {128, 1, 2, 0}, {0, 129, 2, 0}, { 0, 1, 130, 0}, { 0, 1, 2, 0} }, /* 35 */ + { {128, 0, 0, 0}, {1, 1, 129, 1}, { 2, 2, 130, 2}, { 0, 0, 0, 0} }, /* 36 */ + { {128, 1, 2, 0}, {1, 2, 0, 1}, {130, 0, 129, 2}, { 0, 1, 2, 0} }, /* 37 */ + { {128, 1, 2, 0}, {2, 0, 1, 2}, {129, 130, 0, 1}, { 0, 1, 2, 0} }, /* 38 */ + { {128, 0, 1, 1}, {2, 2, 0, 0}, { 1, 1, 130, 2}, { 0, 0, 1, 129} }, /* 39 */ + { {128, 0, 1, 1}, {1, 1, 130, 2}, { 2, 2, 0, 0}, { 0, 0, 1, 129} }, /* 40 */ + { {128, 1, 0, 129}, {0, 1, 0, 1}, { 2, 2, 2, 2}, { 2, 2, 2, 130} }, /* 41 */ + { {128, 0, 0, 0}, {0, 0, 0, 0}, {130, 1, 2, 1}, { 2, 1, 2, 129} }, /* 42 */ + { {128, 0, 2, 2}, {1, 129, 2, 2}, { 0, 0, 2, 2}, { 1, 1, 2, 130} }, /* 43 */ + { {128, 0, 2, 130}, {0, 0, 1, 1}, { 0, 0, 2, 2}, { 0, 0, 1, 129} }, /* 44 */ + { {128, 2, 2, 0}, {1, 2, 130, 1}, { 0, 2, 2, 0}, { 1, 2, 2, 129} }, /* 45 */ + { {128, 1, 0, 1}, {2, 2, 130, 2}, { 2, 2, 2, 2}, { 0, 1, 0, 129} }, /* 46 */ + { {128, 0, 0, 0}, {2, 1, 2, 1}, {130, 1, 2, 1}, { 2, 1, 2, 129} }, /* 47 */ + { {128, 1, 0, 129}, {0, 1, 0, 1}, { 0, 1, 0, 1}, { 2, 2, 2, 130} }, /* 48 */ + { {128, 2, 2, 130}, {0, 1, 1, 1}, { 0, 2, 2, 2}, { 0, 1, 1, 129} }, /* 49 */ + { {128, 0, 0, 2}, {1, 129, 1, 2}, { 0, 0, 0, 2}, { 1, 1, 1, 130} }, /* 50 */ + { {128, 0, 0, 0}, {2, 129, 1, 2}, { 2, 1, 1, 2}, { 2, 1, 1, 130} }, /* 51 */ + { {128, 2, 2, 2}, {0, 129, 1, 1}, { 0, 1, 1, 1}, { 0, 2, 2, 130} }, /* 52 */ + { {128, 0, 0, 2}, {1, 1, 1, 2}, {129, 1, 1, 2}, { 0, 0, 0, 130} }, /* 53 */ + { {128, 1, 1, 0}, {0, 129, 1, 0}, { 0, 1, 1, 0}, { 2, 2, 2, 130} }, /* 54 */ + { {128, 0, 0, 0}, {0, 0, 0, 0}, { 2, 1, 129, 2}, { 2, 1, 1, 130} }, /* 55 */ + { {128, 1, 1, 0}, {0, 129, 1, 0}, { 2, 2, 2, 2}, { 2, 2, 2, 130} }, /* 56 */ + { {128, 0, 2, 2}, {0, 0, 1, 1}, { 0, 0, 129, 1}, { 0, 0, 2, 130} }, /* 57 */ + { {128, 0, 2, 2}, {1, 1, 2, 2}, {129, 1, 2, 2}, { 0, 0, 2, 130} }, /* 58 */ + { {128, 0, 0, 0}, {0, 0, 0, 0}, { 0, 0, 0, 0}, { 2, 129, 1, 130} }, /* 59 */ + { {128, 0, 0, 130}, {0, 0, 0, 1}, { 0, 0, 0, 2}, { 0, 0, 0, 129} }, /* 60 */ + { {128, 2, 2, 2}, {1, 2, 2, 2}, { 0, 2, 2, 2}, {129, 2, 2, 130} }, /* 61 */ + { {128, 1, 0, 129}, {2, 2, 2, 2}, { 2, 2, 2, 2}, { 2, 2, 2, 130} }, /* 62 */ + { {128, 1, 1, 129}, {2, 0, 1, 1}, {130, 2, 0, 1}, { 2, 2, 2, 0} } /* 63 */ + } + }; + + static int aWeight2[] = { 0, 21, 43, 64 }; + static int aWeight3[] = { 0, 9, 18, 27, 37, 46, 55, 64 }; + static int aWeight4[] = { 0, 4, 9, 13, 17, 21, 26, 30, 34, 38, 43, 47, 51, 55, 60, 64 }; + + static unsigned char sModeHasPBits = 0b11001011; + + bcdec__bitstream_t bstream; + int mode, partition, numPartitions, numEndpoints, i, j, k, rotation, partitionSet; + int indexSelectionBit, indexBits, indexBits2, index, index2; + int endpoints[6][4]; + char indices[4][4]; + int r, g, b, a; + int* weights, * weights2; + unsigned char* decompressed; + + decompressed = (unsigned char*)decompressedBlock; + + bstream.low = ((unsigned long long*)compressedBlock)[0]; + bstream.high = ((unsigned long long*)compressedBlock)[1]; + + for (mode = 0; mode < 8 && (0 == bcdec__bitstream_read_bit(&bstream)); ++mode); + + /* unexpected mode, clear the block (transparent black) */ + if (mode >= 8) { + for (i = 0; i < 4; ++i) { + for (j = 0; j < 4; ++j) { + decompressed[j * 4 + 0] = 0; + decompressed[j * 4 + 1] = 0; + decompressed[j * 4 + 2] = 0; + decompressed[j * 4 + 3] = 0; + } + decompressed += destinationPitch; + } + + return; + } + + partition = 0; + numPartitions = 1; + rotation = 0; + indexSelectionBit = 0; + + if (mode == 0 || mode == 1 || mode == 2 || mode == 3 || mode == 7) { + numPartitions = (mode == 0 || mode == 2) ? 3 : 2; + partition = bcdec__bitstream_read_bits(&bstream, (mode == 0) ? 4 : 6); + } + + numEndpoints = numPartitions * 2; + + if (mode == 4 || mode == 5) { + rotation = bcdec__bitstream_read_bits(&bstream, 2); + + if (mode == 4) { + indexSelectionBit = bcdec__bitstream_read_bit(&bstream); + } + } + + /* Extract endpoints */ + /* RGB */ + for (i = 0; i < 3; ++i) { + for (j = 0; j < numEndpoints; ++j) { + endpoints[j][i] = bcdec__bitstream_read_bits(&bstream, actual_bits_count[0][mode]); + } + } + /* Alpha (if any) */ + if (actual_bits_count[1][mode] > 0) { + for (j = 0; j < numEndpoints; ++j) { + endpoints[j][3] = bcdec__bitstream_read_bits(&bstream, actual_bits_count[1][mode]); + } + } + + /* Fully decode endpoints */ + /* First handle modes that have P-bits */ + if (mode == 0 || mode == 1 || mode == 3 || mode == 6 || mode == 7) { + for (i = 0; i < numEndpoints; ++i) { + /* component-wise left-shift */ + for (j = 0; j < 4; ++j) { + endpoints[i][j] <<= 1; + } + } + + /* if P-bit is shared */ + if (mode == 1) { + i = bcdec__bitstream_read_bit(&bstream); + j = bcdec__bitstream_read_bit(&bstream); + + /* rgb component-wise insert pbits */ + for (k = 0; k < 3; ++k) { + endpoints[0][k] |= i; + endpoints[1][k] |= i; + endpoints[2][k] |= j; + endpoints[3][k] |= j; + } + } else if (sModeHasPBits & (1 << mode)) { + /* unique P-bit per endpoint */ + for (i = 0; i < numEndpoints; ++i) { + j = bcdec__bitstream_read_bit(&bstream); + for (k = 0; k < 4; ++k) { + endpoints[i][k] |= j; + } + } + } + } + + for (i = 0; i < numEndpoints; ++i) { + /* get color components precision including pbit */ + j = actual_bits_count[0][mode] + ((sModeHasPBits >> mode) & 1); + + for (k = 0; k < 3; ++k) { + /* left shift endpoint components so that their MSB lies in bit 7 */ + endpoints[i][k] = endpoints[i][k] << (8 - j); + /* Replicate each component's MSB into the LSBs revealed by the left-shift operation above */ + endpoints[i][k] = endpoints[i][k] | (endpoints[i][k] >> j); + } + + /* get alpha component precision including pbit */ + j = actual_bits_count[1][mode] + ((sModeHasPBits >> mode) & 1); + + /* left shift endpoint components so that their MSB lies in bit 7 */ + endpoints[i][3] = endpoints[i][3] << (8 - j); + /* Replicate each component's MSB into the LSBs revealed by the left-shift operation above */ + endpoints[i][3] = endpoints[i][3] | (endpoints[i][3] >> j); + } + + /* If this mode does not explicitly define the alpha component */ + /* set alpha equal to 1.0 */ + if (!actual_bits_count[1][mode]) { + for (j = 0; j < numEndpoints; ++j) { + endpoints[j][3] = 0xFF; + } + } + + /* Determine weights tables */ + indexBits = (mode == 0 || mode == 1) ? 3 : ((mode == 6) ? 4 : 2); + indexBits2 = (mode == 4) ? 3 : ((mode == 5) ? 2 : 0); + weights = (indexBits == 2) ? aWeight2 : ((indexBits == 3) ? aWeight3 : aWeight4); + weights2 = (indexBits2 == 2) ? aWeight2 : aWeight3; + + /* Quite inconvenient that indices aren't interleaved so we have to make 2 passes here */ + /* Pass #1: collecting color indices */ + for (i = 0; i < 4; ++i) { + for (j = 0; j < 4; ++j) { + partitionSet = (numPartitions == 1) ? ((i | j) ? 0 : 128) : partition_sets[numPartitions - 2][partition][i][j]; + + indexBits = (mode == 0 || mode == 1) ? 3 : ((mode == 6) ? 4 : 2); + /* fix-up index is specified with one less bit */ + /* The fix-up index for subset 0 is always index 0 */ + if (partitionSet & 0x80) { + indexBits--; + } + + indices[i][j] = bcdec__bitstream_read_bits(&bstream, indexBits); + } + } + + /* Pass #2: reading alpha indices (if any) and interpolating & rotating */ + for (i = 0; i < 4; ++i) { + for (j = 0; j < 4; ++j) { + partitionSet = (numPartitions == 1) ? ((i|j) ? 0 : 128) : partition_sets[numPartitions - 2][partition][i][j]; + partitionSet &= 0x03; + + index = indices[i][j]; + + if (!indexBits2) { + r = bcdec__interpolate(endpoints[partitionSet * 2][0], endpoints[partitionSet * 2 + 1][0], weights, index); + g = bcdec__interpolate(endpoints[partitionSet * 2][1], endpoints[partitionSet * 2 + 1][1], weights, index); + b = bcdec__interpolate(endpoints[partitionSet * 2][2], endpoints[partitionSet * 2 + 1][2], weights, index); + a = bcdec__interpolate(endpoints[partitionSet * 2][3], endpoints[partitionSet * 2 + 1][3], weights, index); + } else { + index2 = bcdec__bitstream_read_bits(&bstream, (i|j) ? indexBits2 : (indexBits2 - 1)); + /* The index value for interpolating color comes from the secondary index bits for the texel + if the mode has an index selection bit and its value is one, and from the primary index bits otherwise. + The alpha index comes from the secondary index bits if the block has a secondary index and + the block either doesn’t have an index selection bit or that bit is zero, and from the primary index bits otherwise. */ + if (!indexSelectionBit) { + r = bcdec__interpolate(endpoints[partitionSet * 2][0], endpoints[partitionSet * 2 + 1][0], weights, index); + g = bcdec__interpolate(endpoints[partitionSet * 2][1], endpoints[partitionSet * 2 + 1][1], weights, index); + b = bcdec__interpolate(endpoints[partitionSet * 2][2], endpoints[partitionSet * 2 + 1][2], weights, index); + a = bcdec__interpolate(endpoints[partitionSet * 2][3], endpoints[partitionSet * 2 + 1][3], weights2, index2); + } else { + r = bcdec__interpolate(endpoints[partitionSet * 2][0], endpoints[partitionSet * 2 + 1][0], weights2, index2); + g = bcdec__interpolate(endpoints[partitionSet * 2][1], endpoints[partitionSet * 2 + 1][1], weights2, index2); + b = bcdec__interpolate(endpoints[partitionSet * 2][2], endpoints[partitionSet * 2 + 1][2], weights2, index2); + a = bcdec__interpolate(endpoints[partitionSet * 2][3], endpoints[partitionSet * 2 + 1][3], weights, index); + } + } + + switch (rotation) { + case 1: { /* 01 – Block format is Scalar(R) Vector(AGB) - swap A and R */ + bcdec__swap_values(&a, &r); + } break; + case 2: { /* 10 – Block format is Scalar(G) Vector(RAB) - swap A and G */ + bcdec__swap_values(&a, &g); + } break; + case 3: { /* 11 - Block format is Scalar(B) Vector(RGA) - swap A and B */ + bcdec__swap_values(&a, &b); + } break; + } + + decompressed[j * 4 + 0] = r; + decompressed[j * 4 + 1] = g; + decompressed[j * 4 + 2] = b; + decompressed[j * 4 + 3] = a; + } + + decompressed += destinationPitch; + } +} + +#endif /* BCDEC_IMPLEMENTATION */ + +#endif /* BCDEC_HEADER_INCLUDED */ + +/* LICENSE: + +This software is available under 2 licenses -- choose whichever you prefer. + +------------------------------------------------------------------------------ +ALTERNATIVE A - MIT License + +Copyright (c) 2022 Sergii Kudlai + +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 - The Unlicense + +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 <https://unlicense.org> + +*/
\ No newline at end of file diff --git a/thirdparty/openxr/COPYING.adoc b/thirdparty/openxr/COPYING.adoc index 18c85fa6c7..d700a19d7b 100644 --- a/thirdparty/openxr/COPYING.adoc +++ b/thirdparty/openxr/COPYING.adoc @@ -6,7 +6,7 @@ This document is shared across a number of OpenXR GitHub projects, as the set of files in those projects is partially overlapping. -(There is a single "source of truth" internal Khronos GitLab repo these +(There is a single "source of truth" internal Khronos GitLab monorepo these GitHub repositories interact with.) == Licenses @@ -17,7 +17,7 @@ https://reuse.software/spec/[REUSE 3.0 specification] with clear copyright holders and license identifier listed for each file, preferably in each file. Where this is not possible, or e.g. when we are using files unmodified from -other open-source projects, license data is listed: +other open source projects, license data is listed: * in an adjacent file of the same name, with the additional extension "`.license`" diff --git a/thirdparty/openxr/include/openxr/openxr.h b/thirdparty/openxr/include/openxr/openxr.h index 9ac66d8c69..f094b0f72b 100644 --- a/thirdparty/openxr/include/openxr/openxr.h +++ b/thirdparty/openxr/include/openxr/openxr.h @@ -26,7 +26,7 @@ extern "C" { ((((major) & 0xffffULL) << 48) | (((minor) & 0xffffULL) << 32) | ((patch) & 0xffffffffULL)) // OpenXR current version number. -#define XR_CURRENT_API_VERSION XR_MAKE_VERSION(1, 1, 38) +#define XR_CURRENT_API_VERSION XR_MAKE_VERSION(1, 1, 41) // OpenXR 1.0 version number #define XR_API_VERSION_1_0 XR_MAKE_VERSION(1, 0, XR_VERSION_PATCH(XR_CURRENT_API_VERSION)) @@ -242,6 +242,11 @@ typedef enum XrResult { XR_ERROR_LOCALIZATION_MAP_PERMISSION_DENIED_ML = -1000139004, XR_ERROR_LOCALIZATION_MAP_ALREADY_EXISTS_ML = -1000139005, XR_ERROR_LOCALIZATION_MAP_CANNOT_EXPORT_CLOUD_MAP_ML = -1000139006, + XR_ERROR_SPATIAL_ANCHORS_PERMISSION_DENIED_ML = -1000140000, + XR_ERROR_SPATIAL_ANCHORS_NOT_LOCALIZED_ML = -1000140001, + XR_ERROR_SPATIAL_ANCHORS_OUT_OF_MAP_BOUNDS_ML = -1000140002, + XR_ERROR_SPATIAL_ANCHORS_SPACE_NOT_LOCATABLE_ML = -1000140003, + XR_ERROR_SPATIAL_ANCHORS_ANCHOR_NOT_FOUND_ML = -1000141000, XR_ERROR_SPATIAL_ANCHOR_NAME_NOT_FOUND_MSFT = -1000142001, XR_ERROR_SPATIAL_ANCHOR_NAME_INVALID_MSFT = -1000142002, XR_SCENE_MARKER_DATA_NOT_STRING_MSFT = 1000147000, @@ -258,6 +263,10 @@ typedef enum XrResult { XR_ERROR_PLANE_DETECTION_PERMISSION_DENIED_EXT = -1000429001, XR_ERROR_FUTURE_PENDING_EXT = -1000469001, XR_ERROR_FUTURE_INVALID_EXT = -1000469002, + XR_ERROR_SYSTEM_NOTIFICATION_PERMISSION_DENIED_ML = -1000473000, + XR_ERROR_SYSTEM_NOTIFICATION_INCOMPATIBLE_SKU_ML = -1000473001, + XR_ERROR_WORLD_MESH_DETECTOR_PERMISSION_DENIED_ML = -1000474000, + XR_ERROR_WORLD_MESH_DETECTOR_SPACE_NOT_LOCATABLE_ML = -1000474001, XR_ERROR_EXTENSION_DEPENDENCY_NOT_ENABLED_KHR = XR_ERROR_EXTENSION_DEPENDENCY_NOT_ENABLED, XR_ERROR_PERMISSION_INSUFFICIENT_KHR = XR_ERROR_PERMISSION_INSUFFICIENT, XR_RESULT_MAX_ENUM = 0x7FFFFFFF @@ -346,6 +355,9 @@ typedef enum XrStructureType { XR_TYPE_GRAPHICS_BINDING_D3D12_KHR = 1000028000, XR_TYPE_SWAPCHAIN_IMAGE_D3D12_KHR = 1000028001, XR_TYPE_GRAPHICS_REQUIREMENTS_D3D12_KHR = 1000028002, + XR_TYPE_GRAPHICS_BINDING_METAL_KHR = 1000029000, + XR_TYPE_SWAPCHAIN_IMAGE_METAL_KHR = 1000029001, + XR_TYPE_GRAPHICS_REQUIREMENTS_METAL_KHR = 1000029002, XR_TYPE_SYSTEM_EYE_GAZE_INTERACTION_PROPERTIES_EXT = 1000030000, XR_TYPE_EYE_GAZE_SAMPLE_TIME_EXT = 1000030001, XR_TYPE_VISIBILITY_MASK_KHR = 1000031000, @@ -492,6 +504,22 @@ typedef enum XrStructureType { XR_TYPE_MAP_LOCALIZATION_REQUEST_INFO_ML = 1000139002, XR_TYPE_LOCALIZATION_MAP_IMPORT_INFO_ML = 1000139003, XR_TYPE_LOCALIZATION_ENABLE_EVENTS_INFO_ML = 1000139004, + XR_TYPE_SPATIAL_ANCHORS_CREATE_INFO_FROM_POSE_ML = 1000140000, + XR_TYPE_CREATE_SPATIAL_ANCHORS_COMPLETION_ML = 1000140001, + XR_TYPE_SPATIAL_ANCHOR_STATE_ML = 1000140002, + XR_TYPE_SPATIAL_ANCHORS_CREATE_STORAGE_INFO_ML = 1000141000, + XR_TYPE_SPATIAL_ANCHORS_QUERY_INFO_RADIUS_ML = 1000141001, + XR_TYPE_SPATIAL_ANCHORS_QUERY_COMPLETION_ML = 1000141002, + XR_TYPE_SPATIAL_ANCHORS_CREATE_INFO_FROM_UUIDS_ML = 1000141003, + XR_TYPE_SPATIAL_ANCHORS_PUBLISH_INFO_ML = 1000141004, + XR_TYPE_SPATIAL_ANCHORS_PUBLISH_COMPLETION_ML = 1000141005, + XR_TYPE_SPATIAL_ANCHORS_DELETE_INFO_ML = 1000141006, + XR_TYPE_SPATIAL_ANCHORS_DELETE_COMPLETION_ML = 1000141007, + XR_TYPE_SPATIAL_ANCHORS_UPDATE_EXPIRATION_INFO_ML = 1000141008, + XR_TYPE_SPATIAL_ANCHORS_UPDATE_EXPIRATION_COMPLETION_ML = 1000141009, + XR_TYPE_SPATIAL_ANCHORS_PUBLISH_COMPLETION_DETAILS_ML = 1000141010, + XR_TYPE_SPATIAL_ANCHORS_DELETE_COMPLETION_DETAILS_ML = 1000141011, + XR_TYPE_SPATIAL_ANCHORS_UPDATE_EXPIRATION_COMPLETION_DETAILS_ML = 1000141012, XR_TYPE_EVENT_DATA_HEADSET_FIT_CHANGED_ML = 1000472000, XR_TYPE_EVENT_DATA_EYE_CALIBRATION_CHANGED_ML = 1000472001, XR_TYPE_USER_CALIBRATION_ENABLE_EVENTS_INFO_ML = 1000472002, @@ -599,6 +627,11 @@ typedef enum XrStructureType { XR_TYPE_FOVEATION_CUSTOM_MODE_INFO_HTC = 1000318002, XR_TYPE_SYSTEM_ANCHOR_PROPERTIES_HTC = 1000319000, XR_TYPE_SPATIAL_ANCHOR_CREATE_INFO_HTC = 1000319001, + XR_TYPE_SYSTEM_BODY_TRACKING_PROPERTIES_HTC = 1000320000, + XR_TYPE_BODY_TRACKER_CREATE_INFO_HTC = 1000320001, + XR_TYPE_BODY_JOINTS_LOCATE_INFO_HTC = 1000320002, + XR_TYPE_BODY_JOINT_LOCATIONS_HTC = 1000320003, + XR_TYPE_BODY_SKELETON_HTC = 1000320004, XR_TYPE_ACTIVE_ACTION_SET_PRIORITIES_EXT = 1000373000, XR_TYPE_SYSTEM_FORCE_FEEDBACK_CURL_PROPERTIES_MNDX = 1000375000, XR_TYPE_FORCE_FEEDBACK_CURL_APPLY_LOCATIONS_MNDX = 1000375001, @@ -617,6 +650,19 @@ typedef enum XrStructureType { XR_TYPE_FUTURE_POLL_RESULT_EXT = 1000469003, XR_TYPE_EVENT_DATA_USER_PRESENCE_CHANGED_EXT = 1000470000, XR_TYPE_SYSTEM_USER_PRESENCE_PROPERTIES_EXT = 1000470001, + XR_TYPE_SYSTEM_NOTIFICATIONS_SET_INFO_ML = 1000473000, + XR_TYPE_WORLD_MESH_DETECTOR_CREATE_INFO_ML = 1000474001, + XR_TYPE_WORLD_MESH_STATE_REQUEST_INFO_ML = 1000474002, + XR_TYPE_WORLD_MESH_BLOCK_STATE_ML = 1000474003, + XR_TYPE_WORLD_MESH_STATE_REQUEST_COMPLETION_ML = 1000474004, + XR_TYPE_WORLD_MESH_BUFFER_RECOMMENDED_SIZE_INFO_ML = 1000474005, + XR_TYPE_WORLD_MESH_BUFFER_SIZE_ML = 1000474006, + XR_TYPE_WORLD_MESH_BUFFER_ML = 1000474007, + XR_TYPE_WORLD_MESH_BLOCK_REQUEST_ML = 1000474008, + XR_TYPE_WORLD_MESH_GET_INFO_ML = 1000474009, + XR_TYPE_WORLD_MESH_BLOCK_ML = 1000474010, + XR_TYPE_WORLD_MESH_REQUEST_COMPLETION_ML = 1000474011, + XR_TYPE_WORLD_MESH_REQUEST_COMPLETION_INFO_ML = 1000474012, XR_TYPE_GRAPHICS_BINDING_VULKAN2_KHR = XR_TYPE_GRAPHICS_BINDING_VULKAN_KHR, XR_TYPE_SWAPCHAIN_IMAGE_VULKAN2_KHR = XR_TYPE_SWAPCHAIN_IMAGE_VULKAN_KHR, XR_TYPE_GRAPHICS_REQUIREMENTS_VULKAN2_KHR = XR_TYPE_GRAPHICS_REQUIREMENTS_VULKAN_KHR, @@ -713,6 +759,7 @@ typedef enum XrObjectType { XR_OBJECT_TYPE_GEOMETRY_INSTANCE_FB = 1000118004, XR_OBJECT_TYPE_MARKER_DETECTOR_ML = 1000138000, XR_OBJECT_TYPE_EXPORTED_LOCALIZATION_MAP_ML = 1000139000, + XR_OBJECT_TYPE_SPATIAL_ANCHORS_STORAGE_ML = 1000141000, XR_OBJECT_TYPE_SPATIAL_ANCHOR_STORE_CONNECTION_MSFT = 1000142000, XR_OBJECT_TYPE_FACE_TRACKER_FB = 1000201000, XR_OBJECT_TYPE_EYE_TRACKER_FB = 1000202000, @@ -723,7 +770,9 @@ typedef enum XrObjectType { XR_OBJECT_TYPE_ENVIRONMENT_DEPTH_PROVIDER_META = 1000291000, XR_OBJECT_TYPE_ENVIRONMENT_DEPTH_SWAPCHAIN_META = 1000291001, XR_OBJECT_TYPE_PASSTHROUGH_HTC = 1000317000, + XR_OBJECT_TYPE_BODY_TRACKER_HTC = 1000320000, XR_OBJECT_TYPE_PLANE_DETECTOR_EXT = 1000429000, + XR_OBJECT_TYPE_WORLD_MESH_DETECTOR_ML = 1000474000, XR_OBJECT_TYPE_MAX_ENUM = 0x7FFFFFFF } XrObjectType; typedef XrFlags64 XrInstanceCreateFlags; @@ -2184,7 +2233,7 @@ typedef struct XrEventDataMainSessionVisibilityChangedEXTX { // XR_VARJO_quad_views is a preprocessor guard. Do not pass it to API calls. #define XR_VARJO_quad_views 1 -#define XR_VARJO_quad_views_SPEC_VERSION 1 +#define XR_VARJO_quad_views_SPEC_VERSION 2 #define XR_VARJO_QUAD_VIEWS_EXTENSION_NAME "XR_VARJO_quad_views" @@ -4982,6 +5031,245 @@ XRAPI_ATTR XrResult XRAPI_CALL xrGetExportedLocalizationMapDataML( #endif /* !XR_NO_PROTOTYPES */ +// XR_ML_spatial_anchors is a preprocessor guard. Do not pass it to API calls. +#define XR_ML_spatial_anchors 1 +XR_DEFINE_OPAQUE_64(XrFutureEXT) +#define XR_ML_spatial_anchors_SPEC_VERSION 1 +#define XR_ML_SPATIAL_ANCHORS_EXTENSION_NAME "XR_ML_spatial_anchors" + +typedef enum XrSpatialAnchorConfidenceML { + XR_SPATIAL_ANCHOR_CONFIDENCE_LOW_ML = 0, + XR_SPATIAL_ANCHOR_CONFIDENCE_MEDIUM_ML = 1, + XR_SPATIAL_ANCHOR_CONFIDENCE_HIGH_ML = 2, + XR_SPATIAL_ANCHOR_CONFIDENCE_MAX_ENUM_ML = 0x7FFFFFFF +} XrSpatialAnchorConfidenceML; +typedef struct XR_MAY_ALIAS XrSpatialAnchorsCreateInfoBaseHeaderML { + XrStructureType type; + const void* XR_MAY_ALIAS next; +} XrSpatialAnchorsCreateInfoBaseHeaderML; + +typedef struct XrSpatialAnchorsCreateInfoFromPoseML { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrSpace baseSpace; + XrPosef poseInBaseSpace; + XrTime time; +} XrSpatialAnchorsCreateInfoFromPoseML; + +typedef struct XrCreateSpatialAnchorsCompletionML { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrResult futureResult; + uint32_t spaceCount; + XrSpace* spaces; +} XrCreateSpatialAnchorsCompletionML; + +typedef struct XrSpatialAnchorStateML { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrSpatialAnchorConfidenceML confidence; +} XrSpatialAnchorStateML; + +typedef XrResult (XRAPI_PTR *PFN_xrCreateSpatialAnchorsAsyncML)(XrSession session, const XrSpatialAnchorsCreateInfoBaseHeaderML* createInfo, XrFutureEXT* future); +typedef XrResult (XRAPI_PTR *PFN_xrCreateSpatialAnchorsCompleteML)(XrSession session, XrFutureEXT future, XrCreateSpatialAnchorsCompletionML* completion); +typedef XrResult (XRAPI_PTR *PFN_xrGetSpatialAnchorStateML)(XrSpace anchor, XrSpatialAnchorStateML* state); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrCreateSpatialAnchorsAsyncML( + XrSession session, + const XrSpatialAnchorsCreateInfoBaseHeaderML* createInfo, + XrFutureEXT* future); + +XRAPI_ATTR XrResult XRAPI_CALL xrCreateSpatialAnchorsCompleteML( + XrSession session, + XrFutureEXT future, + XrCreateSpatialAnchorsCompletionML* completion); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetSpatialAnchorStateML( + XrSpace anchor, + XrSpatialAnchorStateML* state); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +// XR_ML_spatial_anchors_storage is a preprocessor guard. Do not pass it to API calls. +#define XR_ML_spatial_anchors_storage 1 +XR_DEFINE_HANDLE(XrSpatialAnchorsStorageML) +#define XR_ML_spatial_anchors_storage_SPEC_VERSION 1 +#define XR_ML_SPATIAL_ANCHORS_STORAGE_EXTENSION_NAME "XR_ML_spatial_anchors_storage" +typedef struct XrSpatialAnchorsCreateStorageInfoML { + XrStructureType type; + const void* XR_MAY_ALIAS next; +} XrSpatialAnchorsCreateStorageInfoML; + +typedef struct XR_MAY_ALIAS XrSpatialAnchorsQueryInfoBaseHeaderML { + XrStructureType type; + const void* XR_MAY_ALIAS next; +} XrSpatialAnchorsQueryInfoBaseHeaderML; + +typedef struct XrSpatialAnchorsQueryInfoRadiusML { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrSpace baseSpace; + XrVector3f center; + XrTime time; + float radius; +} XrSpatialAnchorsQueryInfoRadiusML; + +typedef struct XrSpatialAnchorsQueryCompletionML { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrResult futureResult; + uint32_t uuidCapacityInput; + uint32_t uuidCountOutput; + XrUuidEXT* uuids; +} XrSpatialAnchorsQueryCompletionML; + +typedef struct XrSpatialAnchorsCreateInfoFromUuidsML { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrSpatialAnchorsStorageML storage; + uint32_t uuidCount; + const XrUuidEXT* uuids; +} XrSpatialAnchorsCreateInfoFromUuidsML; + +typedef struct XrSpatialAnchorsPublishInfoML { + XrStructureType type; + const void* XR_MAY_ALIAS next; + uint32_t anchorCount; + const XrSpace* anchors; + uint64_t expiration; +} XrSpatialAnchorsPublishInfoML; + +typedef struct XrSpatialAnchorsPublishCompletionML { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrResult futureResult; + uint32_t uuidCount; + XrUuidEXT* uuids; +} XrSpatialAnchorsPublishCompletionML; + +typedef struct XrSpatialAnchorsDeleteInfoML { + XrStructureType type; + const void* XR_MAY_ALIAS next; + uint32_t uuidCount; + const XrUuidEXT* uuids; +} XrSpatialAnchorsDeleteInfoML; + +typedef struct XrSpatialAnchorsDeleteCompletionML { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrResult futureResult; +} XrSpatialAnchorsDeleteCompletionML; + +typedef struct XrSpatialAnchorsUpdateExpirationInfoML { + XrStructureType type; + const void* XR_MAY_ALIAS next; + uint32_t uuidCount; + const XrUuidEXT* uuids; + uint64_t expiration; +} XrSpatialAnchorsUpdateExpirationInfoML; + +typedef struct XrSpatialAnchorsUpdateExpirationCompletionML { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrResult futureResult; +} XrSpatialAnchorsUpdateExpirationCompletionML; + +typedef struct XrSpatialAnchorCompletionResultML { + XrUuidEXT uuid; + XrResult result; +} XrSpatialAnchorCompletionResultML; + +// XrSpatialAnchorsPublishCompletionDetailsML extends XrSpatialAnchorsPublishCompletionML +typedef struct XrSpatialAnchorsPublishCompletionDetailsML { + XrStructureType type; + void* XR_MAY_ALIAS next; + uint32_t resultCount; + XrSpatialAnchorCompletionResultML* results; +} XrSpatialAnchorsPublishCompletionDetailsML; + +// XrSpatialAnchorsDeleteCompletionDetailsML extends XrSpatialAnchorsDeleteCompletionML +typedef struct XrSpatialAnchorsDeleteCompletionDetailsML { + XrStructureType type; + void* XR_MAY_ALIAS next; + uint32_t resultCount; + XrSpatialAnchorCompletionResultML* results; +} XrSpatialAnchorsDeleteCompletionDetailsML; + +// XrSpatialAnchorsUpdateExpirationCompletionDetailsML extends XrSpatialAnchorsUpdateExpirationCompletionML +typedef struct XrSpatialAnchorsUpdateExpirationCompletionDetailsML { + XrStructureType type; + void* XR_MAY_ALIAS next; + uint32_t resultCount; + XrSpatialAnchorCompletionResultML* results; +} XrSpatialAnchorsUpdateExpirationCompletionDetailsML; + +typedef XrResult (XRAPI_PTR *PFN_xrCreateSpatialAnchorsStorageML)(XrSession session, const XrSpatialAnchorsCreateStorageInfoML* createInfo, XrSpatialAnchorsStorageML* storage); +typedef XrResult (XRAPI_PTR *PFN_xrDestroySpatialAnchorsStorageML)(XrSpatialAnchorsStorageML storage); +typedef XrResult (XRAPI_PTR *PFN_xrQuerySpatialAnchorsAsyncML)(XrSpatialAnchorsStorageML storage, const XrSpatialAnchorsQueryInfoBaseHeaderML* queryInfo, XrFutureEXT* future); +typedef XrResult (XRAPI_PTR *PFN_xrQuerySpatialAnchorsCompleteML)(XrSpatialAnchorsStorageML storage, XrFutureEXT future, XrSpatialAnchorsQueryCompletionML* completion); +typedef XrResult (XRAPI_PTR *PFN_xrPublishSpatialAnchorsAsyncML)(XrSpatialAnchorsStorageML storage, const XrSpatialAnchorsPublishInfoML* publishInfo, XrFutureEXT* future); +typedef XrResult (XRAPI_PTR *PFN_xrPublishSpatialAnchorsCompleteML)(XrSpatialAnchorsStorageML storage, XrFutureEXT future, XrSpatialAnchorsPublishCompletionML* completion); +typedef XrResult (XRAPI_PTR *PFN_xrDeleteSpatialAnchorsAsyncML)(XrSpatialAnchorsStorageML storage, const XrSpatialAnchorsDeleteInfoML* deleteInfo, XrFutureEXT* future); +typedef XrResult (XRAPI_PTR *PFN_xrDeleteSpatialAnchorsCompleteML)(XrSpatialAnchorsStorageML storage, XrFutureEXT future, XrSpatialAnchorsDeleteCompletionML* completion); +typedef XrResult (XRAPI_PTR *PFN_xrUpdateSpatialAnchorsExpirationAsyncML)(XrSpatialAnchorsStorageML storage, const XrSpatialAnchorsUpdateExpirationInfoML* updateInfo, XrFutureEXT* future); +typedef XrResult (XRAPI_PTR *PFN_xrUpdateSpatialAnchorsExpirationCompleteML)(XrSpatialAnchorsStorageML storage, XrFutureEXT future, XrSpatialAnchorsUpdateExpirationCompletionML* completion); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrCreateSpatialAnchorsStorageML( + XrSession session, + const XrSpatialAnchorsCreateStorageInfoML* createInfo, + XrSpatialAnchorsStorageML* storage); + +XRAPI_ATTR XrResult XRAPI_CALL xrDestroySpatialAnchorsStorageML( + XrSpatialAnchorsStorageML storage); + +XRAPI_ATTR XrResult XRAPI_CALL xrQuerySpatialAnchorsAsyncML( + XrSpatialAnchorsStorageML storage, + const XrSpatialAnchorsQueryInfoBaseHeaderML* queryInfo, + XrFutureEXT* future); + +XRAPI_ATTR XrResult XRAPI_CALL xrQuerySpatialAnchorsCompleteML( + XrSpatialAnchorsStorageML storage, + XrFutureEXT future, + XrSpatialAnchorsQueryCompletionML* completion); + +XRAPI_ATTR XrResult XRAPI_CALL xrPublishSpatialAnchorsAsyncML( + XrSpatialAnchorsStorageML storage, + const XrSpatialAnchorsPublishInfoML* publishInfo, + XrFutureEXT* future); + +XRAPI_ATTR XrResult XRAPI_CALL xrPublishSpatialAnchorsCompleteML( + XrSpatialAnchorsStorageML storage, + XrFutureEXT future, + XrSpatialAnchorsPublishCompletionML* completion); + +XRAPI_ATTR XrResult XRAPI_CALL xrDeleteSpatialAnchorsAsyncML( + XrSpatialAnchorsStorageML storage, + const XrSpatialAnchorsDeleteInfoML* deleteInfo, + XrFutureEXT* future); + +XRAPI_ATTR XrResult XRAPI_CALL xrDeleteSpatialAnchorsCompleteML( + XrSpatialAnchorsStorageML storage, + XrFutureEXT future, + XrSpatialAnchorsDeleteCompletionML* completion); + +XRAPI_ATTR XrResult XRAPI_CALL xrUpdateSpatialAnchorsExpirationAsyncML( + XrSpatialAnchorsStorageML storage, + const XrSpatialAnchorsUpdateExpirationInfoML* updateInfo, + XrFutureEXT* future); + +XRAPI_ATTR XrResult XRAPI_CALL xrUpdateSpatialAnchorsExpirationCompleteML( + XrSpatialAnchorsStorageML storage, + XrFutureEXT future, + XrSpatialAnchorsUpdateExpirationCompletionML* completion); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + // XR_MSFT_spatial_anchor_persistence is a preprocessor guard. Do not pass it to API calls. #define XR_MSFT_spatial_anchor_persistence 1 XR_DEFINE_HANDLE(XrSpatialAnchorStoreConnectionMSFT) @@ -7052,6 +7340,131 @@ XRAPI_ATTR XrResult XRAPI_CALL xrGetSpatialAnchorNameHTC( #endif /* !XR_NO_PROTOTYPES */ +// XR_HTC_body_tracking is a preprocessor guard. Do not pass it to API calls. +#define XR_HTC_body_tracking 1 + +#define XR_BODY_JOINT_COUNT_HTC 26 + +XR_DEFINE_HANDLE(XrBodyTrackerHTC) +#define XR_HTC_body_tracking_SPEC_VERSION 1 +#define XR_HTC_BODY_TRACKING_EXTENSION_NAME "XR_HTC_body_tracking" + +typedef enum XrBodyJointHTC { + XR_BODY_JOINT_PELVIS_HTC = 0, + XR_BODY_JOINT_LEFT_HIP_HTC = 1, + XR_BODY_JOINT_LEFT_KNEE_HTC = 2, + XR_BODY_JOINT_LEFT_ANKLE_HTC = 3, + XR_BODY_JOINT_LEFT_FEET_HTC = 4, + XR_BODY_JOINT_RIGHT_HIP_HTC = 5, + XR_BODY_JOINT_RIGHT_KNEE_HTC = 6, + XR_BODY_JOINT_RIGHT_ANKLE_HTC = 7, + XR_BODY_JOINT_RIGHT_FEET_HTC = 8, + XR_BODY_JOINT_WAIST_HTC = 9, + XR_BODY_JOINT_SPINE_LOWER_HTC = 10, + XR_BODY_JOINT_SPINE_MIDDLE_HTC = 11, + XR_BODY_JOINT_SPINE_HIGH_HTC = 12, + XR_BODY_JOINT_CHEST_HTC = 13, + XR_BODY_JOINT_NECK_HTC = 14, + XR_BODY_JOINT_HEAD_HTC = 15, + XR_BODY_JOINT_LEFT_CLAVICLE_HTC = 16, + XR_BODY_JOINT_LEFT_SCAPULA_HTC = 17, + XR_BODY_JOINT_LEFT_ARM_HTC = 18, + XR_BODY_JOINT_LEFT_ELBOW_HTC = 19, + XR_BODY_JOINT_LEFT_WRIST_HTC = 20, + XR_BODY_JOINT_RIGHT_CLAVICLE_HTC = 21, + XR_BODY_JOINT_RIGHT_SCAPULA_HTC = 22, + XR_BODY_JOINT_RIGHT_ARM_HTC = 23, + XR_BODY_JOINT_RIGHT_ELBOW_HTC = 24, + XR_BODY_JOINT_RIGHT_WRIST_HTC = 25, + XR_BODY_JOINT_MAX_ENUM_HTC = 0x7FFFFFFF +} XrBodyJointHTC; + +typedef enum XrBodyJointSetHTC { + XR_BODY_JOINT_SET_FULL_HTC = 0, + XR_BODY_JOINT_SET_MAX_ENUM_HTC = 0x7FFFFFFF +} XrBodyJointSetHTC; + +typedef enum XrBodyJointConfidenceHTC { + XR_BODY_JOINT_CONFIDENCE_NONE_HTC = 0, + XR_BODY_JOINT_CONFIDENCE_LOW_HTC = 1, + XR_BODY_JOINT_CONFIDENCE_HIGH_HTC = 2, + XR_BODY_JOINT_CONFIDENCE_MAX_ENUM_HTC = 0x7FFFFFFF +} XrBodyJointConfidenceHTC; +// XrSystemBodyTrackingPropertiesHTC extends XrSystemProperties +typedef struct XrSystemBodyTrackingPropertiesHTC { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrBool32 supportsBodyTracking; +} XrSystemBodyTrackingPropertiesHTC; + +typedef struct XrBodyTrackerCreateInfoHTC { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrBodyJointSetHTC bodyJointSet; +} XrBodyTrackerCreateInfoHTC; + +typedef struct XrBodyJointsLocateInfoHTC { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrSpace baseSpace; + XrTime time; +} XrBodyJointsLocateInfoHTC; + +typedef struct XrBodyJointLocationHTC { + XrSpaceLocationFlags locationFlags; + XrPosef pose; +} XrBodyJointLocationHTC; + +typedef struct XrBodyJointLocationsHTC { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrSpaceLocationFlags combinedLocationFlags; + XrBodyJointConfidenceHTC confidenceLevel; + uint32_t jointLocationCount; + XrBodyJointLocationHTC* jointLocations; + uint32_t skeletonGenerationId; +} XrBodyJointLocationsHTC; + +typedef struct XrBodySkeletonJointHTC { + XrPosef pose; +} XrBodySkeletonJointHTC; + +typedef struct XrBodySkeletonHTC { + XrStructureType type; + void* XR_MAY_ALIAS next; + uint32_t jointCount; + XrBodySkeletonJointHTC* joints; +} XrBodySkeletonHTC; + +typedef XrResult (XRAPI_PTR *PFN_xrCreateBodyTrackerHTC)(XrSession session, const XrBodyTrackerCreateInfoHTC* createInfo, XrBodyTrackerHTC* bodyTracker); +typedef XrResult (XRAPI_PTR *PFN_xrDestroyBodyTrackerHTC)(XrBodyTrackerHTC bodyTracker); +typedef XrResult (XRAPI_PTR *PFN_xrLocateBodyJointsHTC)(XrBodyTrackerHTC bodyTracker, const XrBodyJointsLocateInfoHTC* locateInfo, XrBodyJointLocationsHTC* locations); +typedef XrResult (XRAPI_PTR *PFN_xrGetBodySkeletonHTC)(XrBodyTrackerHTC bodyTracker, XrSpace baseSpace, uint32_t skeletonGenerationId, XrBodySkeletonHTC* skeleton); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrCreateBodyTrackerHTC( + XrSession session, + const XrBodyTrackerCreateInfoHTC* createInfo, + XrBodyTrackerHTC* bodyTracker); + +XRAPI_ATTR XrResult XRAPI_CALL xrDestroyBodyTrackerHTC( + XrBodyTrackerHTC bodyTracker); + +XRAPI_ATTR XrResult XRAPI_CALL xrLocateBodyJointsHTC( + XrBodyTrackerHTC bodyTracker, + const XrBodyJointsLocateInfoHTC* locateInfo, + XrBodyJointLocationsHTC* locations); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetBodySkeletonHTC( + XrBodyTrackerHTC bodyTracker, + XrSpace baseSpace, + uint32_t skeletonGenerationId, + XrBodySkeletonHTC* skeleton); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + // XR_EXT_active_action_set_priority is a preprocessor guard. Do not pass it to API calls. #define XR_EXT_active_action_set_priority 1 #define XR_EXT_active_action_set_priority_SPEC_VERSION 1 @@ -7313,7 +7726,6 @@ XRAPI_ATTR XrResult XRAPI_CALL xrGetPlanePolygonBufferEXT( // XR_EXT_future is a preprocessor guard. Do not pass it to API calls. #define XR_EXT_future 1 -XR_DEFINE_OPAQUE_64(XrFutureEXT) #define XR_EXT_future_SPEC_VERSION 1 #define XR_EXT_FUTURE_EXTENSION_NAME "XR_EXT_future" #define XR_NULL_FUTURE_EXT 0 @@ -7440,6 +7852,232 @@ XRAPI_ATTR XrResult XRAPI_CALL xrEnableUserCalibrationEventsML( #endif /* !XR_NO_PROTOTYPES */ +// XR_ML_system_notifications is a preprocessor guard. Do not pass it to API calls. +#define XR_ML_system_notifications 1 +#define XR_ML_system_notifications_SPEC_VERSION 1 +#define XR_ML_SYSTEM_NOTIFICATIONS_EXTENSION_NAME "XR_ML_system_notifications" +typedef struct XrSystemNotificationsSetInfoML { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrBool32 suppressNotifications; +} XrSystemNotificationsSetInfoML; + +typedef XrResult (XRAPI_PTR *PFN_xrSetSystemNotificationsML)(XrInstance instance, const XrSystemNotificationsSetInfoML* info); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrSetSystemNotificationsML( + XrInstance instance, + const XrSystemNotificationsSetInfoML* info); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +// XR_ML_world_mesh_detection is a preprocessor guard. Do not pass it to API calls. +#define XR_ML_world_mesh_detection 1 +XR_DEFINE_HANDLE(XrWorldMeshDetectorML) +#define XR_ML_world_mesh_detection_SPEC_VERSION 1 +#define XR_ML_WORLD_MESH_DETECTION_EXTENSION_NAME "XR_ML_world_mesh_detection" + +typedef enum XrWorldMeshDetectorLodML { + XR_WORLD_MESH_DETECTOR_LOD_MINIMUM_ML = 0, + XR_WORLD_MESH_DETECTOR_LOD_MEDIUM_ML = 1, + XR_WORLD_MESH_DETECTOR_LOD_MAXIMUM_ML = 2, + XR_WORLD_MESH_DETECTOR_LOD_MAX_ENUM_ML = 0x7FFFFFFF +} XrWorldMeshDetectorLodML; + +typedef enum XrWorldMeshBlockStatusML { + XR_WORLD_MESH_BLOCK_STATUS_NEW_ML = 0, + XR_WORLD_MESH_BLOCK_STATUS_UPDATED_ML = 1, + XR_WORLD_MESH_BLOCK_STATUS_DELETED_ML = 2, + XR_WORLD_MESH_BLOCK_STATUS_UNCHANGED_ML = 3, + XR_WORLD_MESH_BLOCK_STATUS_MAX_ENUM_ML = 0x7FFFFFFF +} XrWorldMeshBlockStatusML; + +typedef enum XrWorldMeshBlockResultML { + XR_WORLD_MESH_BLOCK_RESULT_SUCCESS_ML = 0, + XR_WORLD_MESH_BLOCK_RESULT_FAILED_ML = 1, + XR_WORLD_MESH_BLOCK_RESULT_PENDING_ML = 2, + XR_WORLD_MESH_BLOCK_RESULT_PARTIAL_UPDATE_ML = 3, + XR_WORLD_MESH_BLOCK_RESULT_MAX_ENUM_ML = 0x7FFFFFFF +} XrWorldMeshBlockResultML; +typedef XrFlags64 XrWorldMeshDetectorFlagsML; + +// Flag bits for XrWorldMeshDetectorFlagsML +static const XrWorldMeshDetectorFlagsML XR_WORLD_MESH_DETECTOR_POINT_CLOUD_BIT_ML = 0x00000001; +static const XrWorldMeshDetectorFlagsML XR_WORLD_MESH_DETECTOR_COMPUTE_NORMALS_BIT_ML = 0x00000002; +static const XrWorldMeshDetectorFlagsML XR_WORLD_MESH_DETECTOR_COMPUTE_CONFIDENCE_BIT_ML = 0x00000004; +static const XrWorldMeshDetectorFlagsML XR_WORLD_MESH_DETECTOR_PLANARIZE_BIT_ML = 0x00000008; +static const XrWorldMeshDetectorFlagsML XR_WORLD_MESH_DETECTOR_REMOVE_MESH_SKIRT_BIT_ML = 0x00000010; +static const XrWorldMeshDetectorFlagsML XR_WORLD_MESH_DETECTOR_INDEX_ORDER_CW_BIT_ML = 0x00000020; + +typedef struct XrWorldMeshDetectorCreateInfoML { + XrStructureType type; + const void* XR_MAY_ALIAS next; +} XrWorldMeshDetectorCreateInfoML; + +typedef struct XrWorldMeshBlockStateML { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrUuidEXT uuid; + XrPosef meshBoundingBoxCenter; + XrExtent3DfEXT meshBoundingBoxExtents; + XrTime lastUpdateTime; + XrWorldMeshBlockStatusML status; +} XrWorldMeshBlockStateML; + +typedef struct XrWorldMeshStateRequestInfoML { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrSpace baseSpace; + XrTime time; + XrPosef boundingBoxCenter; + XrExtent3DfEXT boundingBoxExtents; +} XrWorldMeshStateRequestInfoML; + +typedef struct XrWorldMeshStateRequestCompletionML { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrResult futureResult; + XrTime timestamp; + uint32_t meshBlockStateCapacityInput; + uint32_t meshBlockStateCountOutput; + XrWorldMeshBlockStateML* meshBlockStates; +} XrWorldMeshStateRequestCompletionML; + +typedef struct XrWorldMeshBufferRecommendedSizeInfoML { + XrStructureType type; + const void* XR_MAY_ALIAS next; + uint32_t maxBlockCount; +} XrWorldMeshBufferRecommendedSizeInfoML; + +typedef struct XrWorldMeshBufferSizeML { + XrStructureType type; + void* XR_MAY_ALIAS next; + uint32_t size; +} XrWorldMeshBufferSizeML; + +typedef struct XrWorldMeshBufferML { + XrStructureType type; + void* XR_MAY_ALIAS next; + uint32_t bufferSize; + void* XR_MAY_ALIAS buffer; +} XrWorldMeshBufferML; + +typedef struct XrWorldMeshBlockRequestML { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrUuidEXT uuid; + XrWorldMeshDetectorLodML lod; +} XrWorldMeshBlockRequestML; + +typedef struct XrWorldMeshGetInfoML { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrWorldMeshDetectorFlagsML flags; + float fillHoleLength; + float disconnectedComponentArea; + uint32_t blockCount; + XrWorldMeshBlockRequestML* blocks; +} XrWorldMeshGetInfoML; + +typedef struct XrWorldMeshBlockML { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrUuidEXT uuid; + XrWorldMeshBlockResultML blockResult; + XrWorldMeshDetectorLodML lod; + XrWorldMeshDetectorFlagsML flags; + uint32_t indexCount; + uint16_t* indexBuffer; + uint32_t vertexCount; + XrVector3f* vertexBuffer; + uint32_t normalCount; + XrVector3f* normalBuffer; + uint32_t confidenceCount; + float* confidenceBuffer; +} XrWorldMeshBlockML; + +typedef struct XrWorldMeshRequestCompletionInfoML { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrSpace meshSpace; + XrTime meshSpaceLocateTime; +} XrWorldMeshRequestCompletionInfoML; + +typedef struct XrWorldMeshRequestCompletionML { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrResult futureResult; + uint32_t blockCount; + XrWorldMeshBlockML* blocks; +} XrWorldMeshRequestCompletionML; + +typedef XrResult (XRAPI_PTR *PFN_xrCreateWorldMeshDetectorML)(XrSession session, const XrWorldMeshDetectorCreateInfoML* createInfo, XrWorldMeshDetectorML* detector); +typedef XrResult (XRAPI_PTR *PFN_xrDestroyWorldMeshDetectorML)(XrWorldMeshDetectorML detector); +typedef XrResult (XRAPI_PTR *PFN_xrRequestWorldMeshStateAsyncML)(XrWorldMeshDetectorML detector, const XrWorldMeshStateRequestInfoML* stateRequest, XrFutureEXT* future); +typedef XrResult (XRAPI_PTR *PFN_xrRequestWorldMeshStateCompleteML)(XrWorldMeshDetectorML detector, XrFutureEXT future, XrWorldMeshStateRequestCompletionML* completion); +typedef XrResult (XRAPI_PTR *PFN_xrGetWorldMeshBufferRecommendSizeML)(XrWorldMeshDetectorML detector, const XrWorldMeshBufferRecommendedSizeInfoML* sizeInfo, XrWorldMeshBufferSizeML* size); +typedef XrResult (XRAPI_PTR *PFN_xrAllocateWorldMeshBufferML)(XrWorldMeshDetectorML detector, const XrWorldMeshBufferSizeML* size, XrWorldMeshBufferML* buffer); +typedef XrResult (XRAPI_PTR *PFN_xrFreeWorldMeshBufferML)(XrWorldMeshDetectorML detector, const XrWorldMeshBufferML* buffer); +typedef XrResult (XRAPI_PTR *PFN_xrRequestWorldMeshAsyncML)(XrWorldMeshDetectorML detector, const XrWorldMeshGetInfoML* getInfo, XrWorldMeshBufferML* buffer, XrFutureEXT* future); +typedef XrResult (XRAPI_PTR *PFN_xrRequestWorldMeshCompleteML)(XrWorldMeshDetectorML detector, const XrWorldMeshRequestCompletionInfoML* completionInfo, XrFutureEXT future, XrWorldMeshRequestCompletionML* completion); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrCreateWorldMeshDetectorML( + XrSession session, + const XrWorldMeshDetectorCreateInfoML* createInfo, + XrWorldMeshDetectorML* detector); + +XRAPI_ATTR XrResult XRAPI_CALL xrDestroyWorldMeshDetectorML( + XrWorldMeshDetectorML detector); + +XRAPI_ATTR XrResult XRAPI_CALL xrRequestWorldMeshStateAsyncML( + XrWorldMeshDetectorML detector, + const XrWorldMeshStateRequestInfoML* stateRequest, + XrFutureEXT* future); + +XRAPI_ATTR XrResult XRAPI_CALL xrRequestWorldMeshStateCompleteML( + XrWorldMeshDetectorML detector, + XrFutureEXT future, + XrWorldMeshStateRequestCompletionML* completion); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetWorldMeshBufferRecommendSizeML( + XrWorldMeshDetectorML detector, + const XrWorldMeshBufferRecommendedSizeInfoML* sizeInfo, + XrWorldMeshBufferSizeML* size); + +XRAPI_ATTR XrResult XRAPI_CALL xrAllocateWorldMeshBufferML( + XrWorldMeshDetectorML detector, + const XrWorldMeshBufferSizeML* size, + XrWorldMeshBufferML* buffer); + +XRAPI_ATTR XrResult XRAPI_CALL xrFreeWorldMeshBufferML( + XrWorldMeshDetectorML detector, + const XrWorldMeshBufferML* buffer); + +XRAPI_ATTR XrResult XRAPI_CALL xrRequestWorldMeshAsyncML( + XrWorldMeshDetectorML detector, + const XrWorldMeshGetInfoML* getInfo, + XrWorldMeshBufferML* buffer, + XrFutureEXT* future); + +XRAPI_ATTR XrResult XRAPI_CALL xrRequestWorldMeshCompleteML( + XrWorldMeshDetectorML detector, + const XrWorldMeshRequestCompletionInfoML* completionInfo, + XrFutureEXT future, + XrWorldMeshRequestCompletionML* completion); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +// XR_ML_view_configuration_depth_range_change is a preprocessor guard. Do not pass it to API calls. +#define XR_ML_view_configuration_depth_range_change 1 +#define XR_ML_view_configuration_depth_range_change_SPEC_VERSION 1 +#define XR_ML_VIEW_CONFIGURATION_DEPTH_RANGE_CHANGE_EXTENSION_NAME "XR_ML_view_configuration_depth_range_change" + + // XR_YVR_controller_interaction is a preprocessor guard. Do not pass it to API calls. #define XR_YVR_controller_interaction 1 #define XR_YVR_controller_interaction_SPEC_VERSION 1 diff --git a/thirdparty/openxr/include/openxr/openxr_platform.h b/thirdparty/openxr/include/openxr/openxr_platform.h index cbe1008906..dfd74aa5d2 100644 --- a/thirdparty/openxr/include/openxr/openxr_platform.h +++ b/thirdparty/openxr/include/openxr/openxr_platform.h @@ -356,6 +356,43 @@ XRAPI_ATTR XrResult XRAPI_CALL xrGetD3D12GraphicsRequirementsKHR( #endif /* !XR_NO_PROTOTYPES */ #endif /* XR_USE_GRAPHICS_API_D3D12 */ +#ifdef XR_USE_GRAPHICS_API_METAL + +// XR_KHR_metal_enable is a preprocessor guard. Do not pass it to API calls. +#define XR_KHR_metal_enable 1 +#define XR_KHR_metal_enable_SPEC_VERSION 1 +#define XR_KHR_METAL_ENABLE_EXTENSION_NAME "XR_KHR_metal_enable" +// XrGraphicsBindingMetalKHR extends XrSessionCreateInfo +typedef struct XrGraphicsBindingMetalKHR { + XrStructureType type; + const void* XR_MAY_ALIAS next; + void* XR_MAY_ALIAS commandQueue; +} XrGraphicsBindingMetalKHR; + +typedef struct XrSwapchainImageMetalKHR { + XrStructureType type; + const void* XR_MAY_ALIAS next; + void* XR_MAY_ALIAS texture; +} XrSwapchainImageMetalKHR; + +typedef struct XrGraphicsRequirementsMetalKHR { + XrStructureType type; + void* XR_MAY_ALIAS next; + void* XR_MAY_ALIAS metalDevice; +} XrGraphicsRequirementsMetalKHR; + +typedef XrResult (XRAPI_PTR *PFN_xrGetMetalGraphicsRequirementsKHR)(XrInstance instance, XrSystemId systemId, XrGraphicsRequirementsMetalKHR* graphicsRequirements); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrGetMetalGraphicsRequirementsKHR( + XrInstance instance, + XrSystemId systemId, + XrGraphicsRequirementsMetalKHR* graphicsRequirements); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ +#endif /* XR_USE_GRAPHICS_API_METAL */ + #ifdef XR_USE_PLATFORM_WIN32 // XR_KHR_win32_convert_performance_counter_time is a preprocessor guard. Do not pass it to API calls. diff --git a/thirdparty/openxr/include/openxr/openxr_reflection.h b/thirdparty/openxr/include/openxr/openxr_reflection.h index b9d45689a7..4bea81c236 100644 --- a/thirdparty/openxr/include/openxr/openxr_reflection.h +++ b/thirdparty/openxr/include/openxr/openxr_reflection.h @@ -128,6 +128,11 @@ XR_ENUM_STR(XrResult); _(XR_ERROR_LOCALIZATION_MAP_PERMISSION_DENIED_ML, -1000139004) \ _(XR_ERROR_LOCALIZATION_MAP_ALREADY_EXISTS_ML, -1000139005) \ _(XR_ERROR_LOCALIZATION_MAP_CANNOT_EXPORT_CLOUD_MAP_ML, -1000139006) \ + _(XR_ERROR_SPATIAL_ANCHORS_PERMISSION_DENIED_ML, -1000140000) \ + _(XR_ERROR_SPATIAL_ANCHORS_NOT_LOCALIZED_ML, -1000140001) \ + _(XR_ERROR_SPATIAL_ANCHORS_OUT_OF_MAP_BOUNDS_ML, -1000140002) \ + _(XR_ERROR_SPATIAL_ANCHORS_SPACE_NOT_LOCATABLE_ML, -1000140003) \ + _(XR_ERROR_SPATIAL_ANCHORS_ANCHOR_NOT_FOUND_ML, -1000141000) \ _(XR_ERROR_SPATIAL_ANCHOR_NAME_NOT_FOUND_MSFT, -1000142001) \ _(XR_ERROR_SPATIAL_ANCHOR_NAME_INVALID_MSFT, -1000142002) \ _(XR_SCENE_MARKER_DATA_NOT_STRING_MSFT, 1000147000) \ @@ -144,6 +149,10 @@ XR_ENUM_STR(XrResult); _(XR_ERROR_PLANE_DETECTION_PERMISSION_DENIED_EXT, -1000429001) \ _(XR_ERROR_FUTURE_PENDING_EXT, -1000469001) \ _(XR_ERROR_FUTURE_INVALID_EXT, -1000469002) \ + _(XR_ERROR_SYSTEM_NOTIFICATION_PERMISSION_DENIED_ML, -1000473000) \ + _(XR_ERROR_SYSTEM_NOTIFICATION_INCOMPATIBLE_SKU_ML, -1000473001) \ + _(XR_ERROR_WORLD_MESH_DETECTOR_PERMISSION_DENIED_ML, -1000474000) \ + _(XR_ERROR_WORLD_MESH_DETECTOR_SPACE_NOT_LOCATABLE_ML, -1000474001) \ _(XR_RESULT_MAX_ENUM, 0x7FFFFFFF) #define XR_LIST_ENUM_XrStructureType(_) \ @@ -229,6 +238,9 @@ XR_ENUM_STR(XrResult); _(XR_TYPE_GRAPHICS_BINDING_D3D12_KHR, 1000028000) \ _(XR_TYPE_SWAPCHAIN_IMAGE_D3D12_KHR, 1000028001) \ _(XR_TYPE_GRAPHICS_REQUIREMENTS_D3D12_KHR, 1000028002) \ + _(XR_TYPE_GRAPHICS_BINDING_METAL_KHR, 1000029000) \ + _(XR_TYPE_SWAPCHAIN_IMAGE_METAL_KHR, 1000029001) \ + _(XR_TYPE_GRAPHICS_REQUIREMENTS_METAL_KHR, 1000029002) \ _(XR_TYPE_SYSTEM_EYE_GAZE_INTERACTION_PROPERTIES_EXT, 1000030000) \ _(XR_TYPE_EYE_GAZE_SAMPLE_TIME_EXT, 1000030001) \ _(XR_TYPE_VISIBILITY_MASK_KHR, 1000031000) \ @@ -375,6 +387,22 @@ XR_ENUM_STR(XrResult); _(XR_TYPE_MAP_LOCALIZATION_REQUEST_INFO_ML, 1000139002) \ _(XR_TYPE_LOCALIZATION_MAP_IMPORT_INFO_ML, 1000139003) \ _(XR_TYPE_LOCALIZATION_ENABLE_EVENTS_INFO_ML, 1000139004) \ + _(XR_TYPE_SPATIAL_ANCHORS_CREATE_INFO_FROM_POSE_ML, 1000140000) \ + _(XR_TYPE_CREATE_SPATIAL_ANCHORS_COMPLETION_ML, 1000140001) \ + _(XR_TYPE_SPATIAL_ANCHOR_STATE_ML, 1000140002) \ + _(XR_TYPE_SPATIAL_ANCHORS_CREATE_STORAGE_INFO_ML, 1000141000) \ + _(XR_TYPE_SPATIAL_ANCHORS_QUERY_INFO_RADIUS_ML, 1000141001) \ + _(XR_TYPE_SPATIAL_ANCHORS_QUERY_COMPLETION_ML, 1000141002) \ + _(XR_TYPE_SPATIAL_ANCHORS_CREATE_INFO_FROM_UUIDS_ML, 1000141003) \ + _(XR_TYPE_SPATIAL_ANCHORS_PUBLISH_INFO_ML, 1000141004) \ + _(XR_TYPE_SPATIAL_ANCHORS_PUBLISH_COMPLETION_ML, 1000141005) \ + _(XR_TYPE_SPATIAL_ANCHORS_DELETE_INFO_ML, 1000141006) \ + _(XR_TYPE_SPATIAL_ANCHORS_DELETE_COMPLETION_ML, 1000141007) \ + _(XR_TYPE_SPATIAL_ANCHORS_UPDATE_EXPIRATION_INFO_ML, 1000141008) \ + _(XR_TYPE_SPATIAL_ANCHORS_UPDATE_EXPIRATION_COMPLETION_ML, 1000141009) \ + _(XR_TYPE_SPATIAL_ANCHORS_PUBLISH_COMPLETION_DETAILS_ML, 1000141010) \ + _(XR_TYPE_SPATIAL_ANCHORS_DELETE_COMPLETION_DETAILS_ML, 1000141011) \ + _(XR_TYPE_SPATIAL_ANCHORS_UPDATE_EXPIRATION_COMPLETION_DETAILS_ML, 1000141012) \ _(XR_TYPE_EVENT_DATA_HEADSET_FIT_CHANGED_ML, 1000472000) \ _(XR_TYPE_EVENT_DATA_EYE_CALIBRATION_CHANGED_ML, 1000472001) \ _(XR_TYPE_USER_CALIBRATION_ENABLE_EVENTS_INFO_ML, 1000472002) \ @@ -482,6 +510,11 @@ XR_ENUM_STR(XrResult); _(XR_TYPE_FOVEATION_CUSTOM_MODE_INFO_HTC, 1000318002) \ _(XR_TYPE_SYSTEM_ANCHOR_PROPERTIES_HTC, 1000319000) \ _(XR_TYPE_SPATIAL_ANCHOR_CREATE_INFO_HTC, 1000319001) \ + _(XR_TYPE_SYSTEM_BODY_TRACKING_PROPERTIES_HTC, 1000320000) \ + _(XR_TYPE_BODY_TRACKER_CREATE_INFO_HTC, 1000320001) \ + _(XR_TYPE_BODY_JOINTS_LOCATE_INFO_HTC, 1000320002) \ + _(XR_TYPE_BODY_JOINT_LOCATIONS_HTC, 1000320003) \ + _(XR_TYPE_BODY_SKELETON_HTC, 1000320004) \ _(XR_TYPE_ACTIVE_ACTION_SET_PRIORITIES_EXT, 1000373000) \ _(XR_TYPE_SYSTEM_FORCE_FEEDBACK_CURL_PROPERTIES_MNDX, 1000375000) \ _(XR_TYPE_FORCE_FEEDBACK_CURL_APPLY_LOCATIONS_MNDX, 1000375001) \ @@ -500,6 +533,19 @@ XR_ENUM_STR(XrResult); _(XR_TYPE_FUTURE_POLL_RESULT_EXT, 1000469003) \ _(XR_TYPE_EVENT_DATA_USER_PRESENCE_CHANGED_EXT, 1000470000) \ _(XR_TYPE_SYSTEM_USER_PRESENCE_PROPERTIES_EXT, 1000470001) \ + _(XR_TYPE_SYSTEM_NOTIFICATIONS_SET_INFO_ML, 1000473000) \ + _(XR_TYPE_WORLD_MESH_DETECTOR_CREATE_INFO_ML, 1000474001) \ + _(XR_TYPE_WORLD_MESH_STATE_REQUEST_INFO_ML, 1000474002) \ + _(XR_TYPE_WORLD_MESH_BLOCK_STATE_ML, 1000474003) \ + _(XR_TYPE_WORLD_MESH_STATE_REQUEST_COMPLETION_ML, 1000474004) \ + _(XR_TYPE_WORLD_MESH_BUFFER_RECOMMENDED_SIZE_INFO_ML, 1000474005) \ + _(XR_TYPE_WORLD_MESH_BUFFER_SIZE_ML, 1000474006) \ + _(XR_TYPE_WORLD_MESH_BUFFER_ML, 1000474007) \ + _(XR_TYPE_WORLD_MESH_BLOCK_REQUEST_ML, 1000474008) \ + _(XR_TYPE_WORLD_MESH_GET_INFO_ML, 1000474009) \ + _(XR_TYPE_WORLD_MESH_BLOCK_ML, 1000474010) \ + _(XR_TYPE_WORLD_MESH_REQUEST_COMPLETION_ML, 1000474011) \ + _(XR_TYPE_WORLD_MESH_REQUEST_COMPLETION_INFO_ML, 1000474012) \ _(XR_STRUCTURE_TYPE_MAX_ENUM, 0x7FFFFFFF) #define XR_LIST_ENUM_XrFormFactor(_) \ @@ -579,6 +625,7 @@ XR_ENUM_STR(XrResult); _(XR_OBJECT_TYPE_GEOMETRY_INSTANCE_FB, 1000118004) \ _(XR_OBJECT_TYPE_MARKER_DETECTOR_ML, 1000138000) \ _(XR_OBJECT_TYPE_EXPORTED_LOCALIZATION_MAP_ML, 1000139000) \ + _(XR_OBJECT_TYPE_SPATIAL_ANCHORS_STORAGE_ML, 1000141000) \ _(XR_OBJECT_TYPE_SPATIAL_ANCHOR_STORE_CONNECTION_MSFT, 1000142000) \ _(XR_OBJECT_TYPE_FACE_TRACKER_FB, 1000201000) \ _(XR_OBJECT_TYPE_EYE_TRACKER_FB, 1000202000) \ @@ -589,7 +636,9 @@ XR_ENUM_STR(XrResult); _(XR_OBJECT_TYPE_ENVIRONMENT_DEPTH_PROVIDER_META, 1000291000) \ _(XR_OBJECT_TYPE_ENVIRONMENT_DEPTH_SWAPCHAIN_META, 1000291001) \ _(XR_OBJECT_TYPE_PASSTHROUGH_HTC, 1000317000) \ + _(XR_OBJECT_TYPE_BODY_TRACKER_HTC, 1000320000) \ _(XR_OBJECT_TYPE_PLANE_DETECTOR_EXT, 1000429000) \ + _(XR_OBJECT_TYPE_WORLD_MESH_DETECTOR_ML, 1000474000) \ _(XR_OBJECT_TYPE_MAX_ENUM, 0x7FFFFFFF) #define XR_LIST_ENUM_XrLoaderInterfaceStructs(_) \ @@ -1053,6 +1102,12 @@ XR_ENUM_STR(XrResult); _(XR_LOCALIZATION_MAP_CONFIDENCE_EXCELLENT_ML, 3) \ _(XR_LOCALIZATION_MAP_CONFIDENCE_MAX_ENUM_ML, 0x7FFFFFFF) +#define XR_LIST_ENUM_XrSpatialAnchorConfidenceML(_) \ + _(XR_SPATIAL_ANCHOR_CONFIDENCE_LOW_ML, 0) \ + _(XR_SPATIAL_ANCHOR_CONFIDENCE_MEDIUM_ML, 1) \ + _(XR_SPATIAL_ANCHOR_CONFIDENCE_HIGH_ML, 2) \ + _(XR_SPATIAL_ANCHOR_CONFIDENCE_MAX_ENUM_ML, 0x7FFFFFFF) + #define XR_LIST_ENUM_XrSceneMarkerTypeMSFT(_) \ _(XR_SCENE_MARKER_TYPE_QR_CODE_MSFT, 1) \ _(XR_SCENE_MARKER_TYPE_MAX_ENUM_MSFT, 0x7FFFFFFF) @@ -1363,6 +1418,45 @@ XR_ENUM_STR(XrResult); _(XR_FOVEATION_LEVEL_HIGH_HTC, 3) \ _(XR_FOVEATION_LEVEL_MAX_ENUM_HTC, 0x7FFFFFFF) +#define XR_LIST_ENUM_XrBodyJointHTC(_) \ + _(XR_BODY_JOINT_PELVIS_HTC, 0) \ + _(XR_BODY_JOINT_LEFT_HIP_HTC, 1) \ + _(XR_BODY_JOINT_LEFT_KNEE_HTC, 2) \ + _(XR_BODY_JOINT_LEFT_ANKLE_HTC, 3) \ + _(XR_BODY_JOINT_LEFT_FEET_HTC, 4) \ + _(XR_BODY_JOINT_RIGHT_HIP_HTC, 5) \ + _(XR_BODY_JOINT_RIGHT_KNEE_HTC, 6) \ + _(XR_BODY_JOINT_RIGHT_ANKLE_HTC, 7) \ + _(XR_BODY_JOINT_RIGHT_FEET_HTC, 8) \ + _(XR_BODY_JOINT_WAIST_HTC, 9) \ + _(XR_BODY_JOINT_SPINE_LOWER_HTC, 10) \ + _(XR_BODY_JOINT_SPINE_MIDDLE_HTC, 11) \ + _(XR_BODY_JOINT_SPINE_HIGH_HTC, 12) \ + _(XR_BODY_JOINT_CHEST_HTC, 13) \ + _(XR_BODY_JOINT_NECK_HTC, 14) \ + _(XR_BODY_JOINT_HEAD_HTC, 15) \ + _(XR_BODY_JOINT_LEFT_CLAVICLE_HTC, 16) \ + _(XR_BODY_JOINT_LEFT_SCAPULA_HTC, 17) \ + _(XR_BODY_JOINT_LEFT_ARM_HTC, 18) \ + _(XR_BODY_JOINT_LEFT_ELBOW_HTC, 19) \ + _(XR_BODY_JOINT_LEFT_WRIST_HTC, 20) \ + _(XR_BODY_JOINT_RIGHT_CLAVICLE_HTC, 21) \ + _(XR_BODY_JOINT_RIGHT_SCAPULA_HTC, 22) \ + _(XR_BODY_JOINT_RIGHT_ARM_HTC, 23) \ + _(XR_BODY_JOINT_RIGHT_ELBOW_HTC, 24) \ + _(XR_BODY_JOINT_RIGHT_WRIST_HTC, 25) \ + _(XR_BODY_JOINT_MAX_ENUM_HTC, 0x7FFFFFFF) + +#define XR_LIST_ENUM_XrBodyJointSetHTC(_) \ + _(XR_BODY_JOINT_SET_FULL_HTC, 0) \ + _(XR_BODY_JOINT_SET_MAX_ENUM_HTC, 0x7FFFFFFF) + +#define XR_LIST_ENUM_XrBodyJointConfidenceHTC(_) \ + _(XR_BODY_JOINT_CONFIDENCE_NONE_HTC, 0) \ + _(XR_BODY_JOINT_CONFIDENCE_LOW_HTC, 1) \ + _(XR_BODY_JOINT_CONFIDENCE_HIGH_HTC, 2) \ + _(XR_BODY_JOINT_CONFIDENCE_MAX_ENUM_HTC, 0x7FFFFFFF) + #define XR_LIST_ENUM_XrForceFeedbackCurlLocationMNDX(_) \ _(XR_FORCE_FEEDBACK_CURL_LOCATION_THUMB_CURL_MNDX, 0) \ _(XR_FORCE_FEEDBACK_CURL_LOCATION_INDEX_CURL_MNDX, 1) \ @@ -1418,6 +1512,26 @@ XR_ENUM_STR(XrResult); _(XR_EYE_CALIBRATION_STATUS_FINE_ML, 3) \ _(XR_EYE_CALIBRATION_STATUS_MAX_ENUM_ML, 0x7FFFFFFF) +#define XR_LIST_ENUM_XrWorldMeshDetectorLodML(_) \ + _(XR_WORLD_MESH_DETECTOR_LOD_MINIMUM_ML, 0) \ + _(XR_WORLD_MESH_DETECTOR_LOD_MEDIUM_ML, 1) \ + _(XR_WORLD_MESH_DETECTOR_LOD_MAXIMUM_ML, 2) \ + _(XR_WORLD_MESH_DETECTOR_LOD_MAX_ENUM_ML, 0x7FFFFFFF) + +#define XR_LIST_ENUM_XrWorldMeshBlockStatusML(_) \ + _(XR_WORLD_MESH_BLOCK_STATUS_NEW_ML, 0) \ + _(XR_WORLD_MESH_BLOCK_STATUS_UPDATED_ML, 1) \ + _(XR_WORLD_MESH_BLOCK_STATUS_DELETED_ML, 2) \ + _(XR_WORLD_MESH_BLOCK_STATUS_UNCHANGED_ML, 3) \ + _(XR_WORLD_MESH_BLOCK_STATUS_MAX_ENUM_ML, 0x7FFFFFFF) + +#define XR_LIST_ENUM_XrWorldMeshBlockResultML(_) \ + _(XR_WORLD_MESH_BLOCK_RESULT_SUCCESS_ML, 0) \ + _(XR_WORLD_MESH_BLOCK_RESULT_FAILED_ML, 1) \ + _(XR_WORLD_MESH_BLOCK_RESULT_PENDING_ML, 2) \ + _(XR_WORLD_MESH_BLOCK_RESULT_PARTIAL_UPDATE_ML, 3) \ + _(XR_WORLD_MESH_BLOCK_RESULT_MAX_ENUM_ML, 0x7FFFFFFF) + #define XR_LIST_BITS_XrInstanceCreateFlags(_) #define XR_LIST_BITS_XrSessionCreateFlags(_) @@ -1622,6 +1736,14 @@ XR_ENUM_STR(XrResult); #define XR_LIST_BITS_XrPlaneDetectorFlagsEXT(_) \ _(XR_PLANE_DETECTOR_ENABLE_CONTOUR_BIT_EXT, 0x00000001) \ +#define XR_LIST_BITS_XrWorldMeshDetectorFlagsML(_) \ + _(XR_WORLD_MESH_DETECTOR_POINT_CLOUD_BIT_ML, 0x00000001) \ + _(XR_WORLD_MESH_DETECTOR_COMPUTE_NORMALS_BIT_ML, 0x00000002) \ + _(XR_WORLD_MESH_DETECTOR_COMPUTE_CONFIDENCE_BIT_ML, 0x00000004) \ + _(XR_WORLD_MESH_DETECTOR_PLANARIZE_BIT_ML, 0x00000008) \ + _(XR_WORLD_MESH_DETECTOR_REMOVE_MESH_SKIRT_BIT_ML, 0x00000010) \ + _(XR_WORLD_MESH_DETECTOR_INDEX_ORDER_CW_BIT_ML, 0x00000020) \ + /// Calls your macro with the name of each member of XrApiLayerProperties, in order. #define XR_LIST_STRUCT_XrApiLayerProperties(_) \ _(type) \ @@ -2442,6 +2564,24 @@ XR_ENUM_STR(XrResult); _(adapterLuid) \ _(minFeatureLevel) \ +/// Calls your macro with the name of each member of XrGraphicsBindingMetalKHR, in order. +#define XR_LIST_STRUCT_XrGraphicsBindingMetalKHR(_) \ + _(type) \ + _(next) \ + _(commandQueue) \ + +/// Calls your macro with the name of each member of XrSwapchainImageMetalKHR, in order. +#define XR_LIST_STRUCT_XrSwapchainImageMetalKHR(_) \ + _(type) \ + _(next) \ + _(texture) \ + +/// Calls your macro with the name of each member of XrGraphicsRequirementsMetalKHR, in order. +#define XR_LIST_STRUCT_XrGraphicsRequirementsMetalKHR(_) \ + _(type) \ + _(next) \ + _(metalDevice) \ + /// Calls your macro with the name of each member of XrVisibilityMaskKHR, in order. #define XR_LIST_STRUCT_XrVisibilityMaskKHR(_) \ _(type) \ @@ -3711,6 +3851,138 @@ XR_ENUM_STR(XrResult); _(next) \ _(enabled) \ +/// Calls your macro with the name of each member of XrSpatialAnchorsCreateInfoBaseHeaderML, in order. +#define XR_LIST_STRUCT_XrSpatialAnchorsCreateInfoBaseHeaderML(_) \ + _(type) \ + _(next) \ + +/// Calls your macro with the name of each member of XrSpatialAnchorsCreateInfoFromPoseML, in order. +#define XR_LIST_STRUCT_XrSpatialAnchorsCreateInfoFromPoseML(_) \ + _(type) \ + _(next) \ + _(baseSpace) \ + _(poseInBaseSpace) \ + _(time) \ + +/// Calls your macro with the name of each member of XrCreateSpatialAnchorsCompletionML, in order. +#define XR_LIST_STRUCT_XrCreateSpatialAnchorsCompletionML(_) \ + _(type) \ + _(next) \ + _(futureResult) \ + _(spaceCount) \ + _(spaces) \ + +/// Calls your macro with the name of each member of XrSpatialAnchorStateML, in order. +#define XR_LIST_STRUCT_XrSpatialAnchorStateML(_) \ + _(type) \ + _(next) \ + _(confidence) \ + +/// Calls your macro with the name of each member of XrSpatialAnchorsCreateStorageInfoML, in order. +#define XR_LIST_STRUCT_XrSpatialAnchorsCreateStorageInfoML(_) \ + _(type) \ + _(next) \ + +/// Calls your macro with the name of each member of XrSpatialAnchorsQueryInfoBaseHeaderML, in order. +#define XR_LIST_STRUCT_XrSpatialAnchorsQueryInfoBaseHeaderML(_) \ + _(type) \ + _(next) \ + +/// Calls your macro with the name of each member of XrSpatialAnchorsQueryInfoRadiusML, in order. +#define XR_LIST_STRUCT_XrSpatialAnchorsQueryInfoRadiusML(_) \ + _(type) \ + _(next) \ + _(baseSpace) \ + _(center) \ + _(time) \ + _(radius) \ + +/// Calls your macro with the name of each member of XrSpatialAnchorsQueryCompletionML, in order. +#define XR_LIST_STRUCT_XrSpatialAnchorsQueryCompletionML(_) \ + _(type) \ + _(next) \ + _(futureResult) \ + _(uuidCapacityInput) \ + _(uuidCountOutput) \ + _(uuids) \ + +/// Calls your macro with the name of each member of XrSpatialAnchorsCreateInfoFromUuidsML, in order. +#define XR_LIST_STRUCT_XrSpatialAnchorsCreateInfoFromUuidsML(_) \ + _(type) \ + _(next) \ + _(storage) \ + _(uuidCount) \ + _(uuids) \ + +/// Calls your macro with the name of each member of XrSpatialAnchorsPublishInfoML, in order. +#define XR_LIST_STRUCT_XrSpatialAnchorsPublishInfoML(_) \ + _(type) \ + _(next) \ + _(anchorCount) \ + _(anchors) \ + _(expiration) \ + +/// Calls your macro with the name of each member of XrSpatialAnchorsPublishCompletionML, in order. +#define XR_LIST_STRUCT_XrSpatialAnchorsPublishCompletionML(_) \ + _(type) \ + _(next) \ + _(futureResult) \ + _(uuidCount) \ + _(uuids) \ + +/// Calls your macro with the name of each member of XrSpatialAnchorsDeleteInfoML, in order. +#define XR_LIST_STRUCT_XrSpatialAnchorsDeleteInfoML(_) \ + _(type) \ + _(next) \ + _(uuidCount) \ + _(uuids) \ + +/// Calls your macro with the name of each member of XrSpatialAnchorsDeleteCompletionML, in order. +#define XR_LIST_STRUCT_XrSpatialAnchorsDeleteCompletionML(_) \ + _(type) \ + _(next) \ + _(futureResult) \ + +/// Calls your macro with the name of each member of XrSpatialAnchorsUpdateExpirationInfoML, in order. +#define XR_LIST_STRUCT_XrSpatialAnchorsUpdateExpirationInfoML(_) \ + _(type) \ + _(next) \ + _(uuidCount) \ + _(uuids) \ + _(expiration) \ + +/// Calls your macro with the name of each member of XrSpatialAnchorsUpdateExpirationCompletionML, in order. +#define XR_LIST_STRUCT_XrSpatialAnchorsUpdateExpirationCompletionML(_) \ + _(type) \ + _(next) \ + _(futureResult) \ + +/// Calls your macro with the name of each member of XrSpatialAnchorCompletionResultML, in order. +#define XR_LIST_STRUCT_XrSpatialAnchorCompletionResultML(_) \ + _(uuid) \ + _(result) \ + +/// Calls your macro with the name of each member of XrSpatialAnchorsPublishCompletionDetailsML, in order. +#define XR_LIST_STRUCT_XrSpatialAnchorsPublishCompletionDetailsML(_) \ + _(type) \ + _(next) \ + _(resultCount) \ + _(results) \ + +/// Calls your macro with the name of each member of XrSpatialAnchorsDeleteCompletionDetailsML, in order. +#define XR_LIST_STRUCT_XrSpatialAnchorsDeleteCompletionDetailsML(_) \ + _(type) \ + _(next) \ + _(resultCount) \ + _(results) \ + +/// Calls your macro with the name of each member of XrSpatialAnchorsUpdateExpirationCompletionDetailsML, in order. +#define XR_LIST_STRUCT_XrSpatialAnchorsUpdateExpirationCompletionDetailsML(_) \ + _(type) \ + _(next) \ + _(resultCount) \ + _(results) \ + /// Calls your macro with the name of each member of XrSpatialAnchorPersistenceNameMSFT, in order. #define XR_LIST_STRUCT_XrSpatialAnchorPersistenceNameMSFT(_) \ _(name) \ @@ -4571,6 +4843,51 @@ XR_ENUM_STR(XrResult); _(poseInSpace) \ _(name) \ +/// Calls your macro with the name of each member of XrSystemBodyTrackingPropertiesHTC, in order. +#define XR_LIST_STRUCT_XrSystemBodyTrackingPropertiesHTC(_) \ + _(type) \ + _(next) \ + _(supportsBodyTracking) \ + +/// Calls your macro with the name of each member of XrBodyTrackerCreateInfoHTC, in order. +#define XR_LIST_STRUCT_XrBodyTrackerCreateInfoHTC(_) \ + _(type) \ + _(next) \ + _(bodyJointSet) \ + +/// Calls your macro with the name of each member of XrBodyJointsLocateInfoHTC, in order. +#define XR_LIST_STRUCT_XrBodyJointsLocateInfoHTC(_) \ + _(type) \ + _(next) \ + _(baseSpace) \ + _(time) \ + +/// Calls your macro with the name of each member of XrBodyJointLocationHTC, in order. +#define XR_LIST_STRUCT_XrBodyJointLocationHTC(_) \ + _(locationFlags) \ + _(pose) \ + +/// Calls your macro with the name of each member of XrBodyJointLocationsHTC, in order. +#define XR_LIST_STRUCT_XrBodyJointLocationsHTC(_) \ + _(type) \ + _(next) \ + _(combinedLocationFlags) \ + _(confidenceLevel) \ + _(jointLocationCount) \ + _(jointLocations) \ + _(skeletonGenerationId) \ + +/// Calls your macro with the name of each member of XrBodySkeletonJointHTC, in order. +#define XR_LIST_STRUCT_XrBodySkeletonJointHTC(_) \ + _(pose) \ + +/// Calls your macro with the name of each member of XrBodySkeletonHTC, in order. +#define XR_LIST_STRUCT_XrBodySkeletonHTC(_) \ + _(type) \ + _(next) \ + _(jointCount) \ + _(joints) \ + /// Calls your macro with the name of each member of XrActiveActionSetPriorityEXT, in order. #define XR_LIST_STRUCT_XrActiveActionSetPriorityEXT(_) \ _(actionSet) \ @@ -4739,6 +5056,114 @@ XR_ENUM_STR(XrResult); _(next) \ _(enabled) \ +/// Calls your macro with the name of each member of XrSystemNotificationsSetInfoML, in order. +#define XR_LIST_STRUCT_XrSystemNotificationsSetInfoML(_) \ + _(type) \ + _(next) \ + _(suppressNotifications) \ + +/// Calls your macro with the name of each member of XrWorldMeshDetectorCreateInfoML, in order. +#define XR_LIST_STRUCT_XrWorldMeshDetectorCreateInfoML(_) \ + _(type) \ + _(next) \ + +/// Calls your macro with the name of each member of XrWorldMeshBlockStateML, in order. +#define XR_LIST_STRUCT_XrWorldMeshBlockStateML(_) \ + _(type) \ + _(next) \ + _(uuid) \ + _(meshBoundingBoxCenter) \ + _(meshBoundingBoxExtents) \ + _(lastUpdateTime) \ + _(status) \ + +/// Calls your macro with the name of each member of XrWorldMeshStateRequestInfoML, in order. +#define XR_LIST_STRUCT_XrWorldMeshStateRequestInfoML(_) \ + _(type) \ + _(next) \ + _(baseSpace) \ + _(time) \ + _(boundingBoxCenter) \ + _(boundingBoxExtents) \ + +/// Calls your macro with the name of each member of XrWorldMeshStateRequestCompletionML, in order. +#define XR_LIST_STRUCT_XrWorldMeshStateRequestCompletionML(_) \ + _(type) \ + _(next) \ + _(futureResult) \ + _(timestamp) \ + _(meshBlockStateCapacityInput) \ + _(meshBlockStateCountOutput) \ + _(meshBlockStates) \ + +/// Calls your macro with the name of each member of XrWorldMeshBufferRecommendedSizeInfoML, in order. +#define XR_LIST_STRUCT_XrWorldMeshBufferRecommendedSizeInfoML(_) \ + _(type) \ + _(next) \ + _(maxBlockCount) \ + +/// Calls your macro with the name of each member of XrWorldMeshBufferSizeML, in order. +#define XR_LIST_STRUCT_XrWorldMeshBufferSizeML(_) \ + _(type) \ + _(next) \ + _(size) \ + +/// Calls your macro with the name of each member of XrWorldMeshBufferML, in order. +#define XR_LIST_STRUCT_XrWorldMeshBufferML(_) \ + _(type) \ + _(next) \ + _(bufferSize) \ + _(buffer) \ + +/// Calls your macro with the name of each member of XrWorldMeshBlockRequestML, in order. +#define XR_LIST_STRUCT_XrWorldMeshBlockRequestML(_) \ + _(type) \ + _(next) \ + _(uuid) \ + _(lod) \ + +/// Calls your macro with the name of each member of XrWorldMeshGetInfoML, in order. +#define XR_LIST_STRUCT_XrWorldMeshGetInfoML(_) \ + _(type) \ + _(next) \ + _(flags) \ + _(fillHoleLength) \ + _(disconnectedComponentArea) \ + _(blockCount) \ + _(blocks) \ + +/// Calls your macro with the name of each member of XrWorldMeshBlockML, in order. +#define XR_LIST_STRUCT_XrWorldMeshBlockML(_) \ + _(type) \ + _(next) \ + _(uuid) \ + _(blockResult) \ + _(lod) \ + _(flags) \ + _(indexCount) \ + _(indexBuffer) \ + _(vertexCount) \ + _(vertexBuffer) \ + _(normalCount) \ + _(normalBuffer) \ + _(confidenceCount) \ + _(confidenceBuffer) \ + +/// Calls your macro with the name of each member of XrWorldMeshRequestCompletionInfoML, in order. +#define XR_LIST_STRUCT_XrWorldMeshRequestCompletionInfoML(_) \ + _(type) \ + _(next) \ + _(meshSpace) \ + _(meshSpaceLocateTime) \ + +/// Calls your macro with the name of each member of XrWorldMeshRequestCompletionML, in order. +#define XR_LIST_STRUCT_XrWorldMeshRequestCompletionML(_) \ + _(type) \ + _(next) \ + _(futureResult) \ + _(blockCount) \ + _(blocks) \ + /// Calls your macro with the structure type name and the XrStructureType constant for @@ -4747,6 +5172,7 @@ XR_ENUM_STR(XrResult); XR_LIST_STRUCTURE_TYPES_CORE(_) \ XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_D3D11(_) \ XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_D3D12(_) \ + XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_METAL(_) \ XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL(_) \ XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL_XR_USE_PLATFORM_WAYLAND(_) \ XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL_XR_USE_PLATFORM_WIN32(_) \ @@ -4962,6 +5388,22 @@ XR_ENUM_STR(XrResult); _(XrMapLocalizationRequestInfoML, XR_TYPE_MAP_LOCALIZATION_REQUEST_INFO_ML) \ _(XrLocalizationMapImportInfoML, XR_TYPE_LOCALIZATION_MAP_IMPORT_INFO_ML) \ _(XrLocalizationEnableEventsInfoML, XR_TYPE_LOCALIZATION_ENABLE_EVENTS_INFO_ML) \ + _(XrSpatialAnchorsCreateInfoFromPoseML, XR_TYPE_SPATIAL_ANCHORS_CREATE_INFO_FROM_POSE_ML) \ + _(XrCreateSpatialAnchorsCompletionML, XR_TYPE_CREATE_SPATIAL_ANCHORS_COMPLETION_ML) \ + _(XrSpatialAnchorStateML, XR_TYPE_SPATIAL_ANCHOR_STATE_ML) \ + _(XrSpatialAnchorsCreateStorageInfoML, XR_TYPE_SPATIAL_ANCHORS_CREATE_STORAGE_INFO_ML) \ + _(XrSpatialAnchorsQueryInfoRadiusML, XR_TYPE_SPATIAL_ANCHORS_QUERY_INFO_RADIUS_ML) \ + _(XrSpatialAnchorsQueryCompletionML, XR_TYPE_SPATIAL_ANCHORS_QUERY_COMPLETION_ML) \ + _(XrSpatialAnchorsCreateInfoFromUuidsML, XR_TYPE_SPATIAL_ANCHORS_CREATE_INFO_FROM_UUIDS_ML) \ + _(XrSpatialAnchorsPublishInfoML, XR_TYPE_SPATIAL_ANCHORS_PUBLISH_INFO_ML) \ + _(XrSpatialAnchorsPublishCompletionML, XR_TYPE_SPATIAL_ANCHORS_PUBLISH_COMPLETION_ML) \ + _(XrSpatialAnchorsDeleteInfoML, XR_TYPE_SPATIAL_ANCHORS_DELETE_INFO_ML) \ + _(XrSpatialAnchorsDeleteCompletionML, XR_TYPE_SPATIAL_ANCHORS_DELETE_COMPLETION_ML) \ + _(XrSpatialAnchorsUpdateExpirationInfoML, XR_TYPE_SPATIAL_ANCHORS_UPDATE_EXPIRATION_INFO_ML) \ + _(XrSpatialAnchorsUpdateExpirationCompletionML, XR_TYPE_SPATIAL_ANCHORS_UPDATE_EXPIRATION_COMPLETION_ML) \ + _(XrSpatialAnchorsPublishCompletionDetailsML, XR_TYPE_SPATIAL_ANCHORS_PUBLISH_COMPLETION_DETAILS_ML) \ + _(XrSpatialAnchorsDeleteCompletionDetailsML, XR_TYPE_SPATIAL_ANCHORS_DELETE_COMPLETION_DETAILS_ML) \ + _(XrSpatialAnchorsUpdateExpirationCompletionDetailsML, XR_TYPE_SPATIAL_ANCHORS_UPDATE_EXPIRATION_COMPLETION_DETAILS_ML) \ _(XrSpatialAnchorPersistenceInfoMSFT, XR_TYPE_SPATIAL_ANCHOR_PERSISTENCE_INFO_MSFT) \ _(XrSpatialAnchorFromPersistedAnchorCreateInfoMSFT, XR_TYPE_SPATIAL_ANCHOR_FROM_PERSISTED_ANCHOR_CREATE_INFO_MSFT) \ _(XrSceneMarkersMSFT, XR_TYPE_SCENE_MARKERS_MSFT) \ @@ -5061,6 +5503,11 @@ XR_ENUM_STR(XrResult); _(XrFoveationCustomModeInfoHTC, XR_TYPE_FOVEATION_CUSTOM_MODE_INFO_HTC) \ _(XrSystemAnchorPropertiesHTC, XR_TYPE_SYSTEM_ANCHOR_PROPERTIES_HTC) \ _(XrSpatialAnchorCreateInfoHTC, XR_TYPE_SPATIAL_ANCHOR_CREATE_INFO_HTC) \ + _(XrSystemBodyTrackingPropertiesHTC, XR_TYPE_SYSTEM_BODY_TRACKING_PROPERTIES_HTC) \ + _(XrBodyTrackerCreateInfoHTC, XR_TYPE_BODY_TRACKER_CREATE_INFO_HTC) \ + _(XrBodyJointsLocateInfoHTC, XR_TYPE_BODY_JOINTS_LOCATE_INFO_HTC) \ + _(XrBodyJointLocationsHTC, XR_TYPE_BODY_JOINT_LOCATIONS_HTC) \ + _(XrBodySkeletonHTC, XR_TYPE_BODY_SKELETON_HTC) \ _(XrActiveActionSetPrioritiesEXT, XR_TYPE_ACTIVE_ACTION_SET_PRIORITIES_EXT) \ _(XrSystemForceFeedbackCurlPropertiesMNDX, XR_TYPE_SYSTEM_FORCE_FEEDBACK_CURL_PROPERTIES_MNDX) \ _(XrForceFeedbackCurlApplyLocationsMNDX, XR_TYPE_FORCE_FEEDBACK_CURL_APPLY_LOCATIONS_MNDX) \ @@ -5082,6 +5529,19 @@ XR_ENUM_STR(XrResult); _(XrEventDataHeadsetFitChangedML, XR_TYPE_EVENT_DATA_HEADSET_FIT_CHANGED_ML) \ _(XrEventDataEyeCalibrationChangedML, XR_TYPE_EVENT_DATA_EYE_CALIBRATION_CHANGED_ML) \ _(XrUserCalibrationEnableEventsInfoML, XR_TYPE_USER_CALIBRATION_ENABLE_EVENTS_INFO_ML) \ + _(XrSystemNotificationsSetInfoML, XR_TYPE_SYSTEM_NOTIFICATIONS_SET_INFO_ML) \ + _(XrWorldMeshDetectorCreateInfoML, XR_TYPE_WORLD_MESH_DETECTOR_CREATE_INFO_ML) \ + _(XrWorldMeshBlockStateML, XR_TYPE_WORLD_MESH_BLOCK_STATE_ML) \ + _(XrWorldMeshStateRequestInfoML, XR_TYPE_WORLD_MESH_STATE_REQUEST_INFO_ML) \ + _(XrWorldMeshStateRequestCompletionML, XR_TYPE_WORLD_MESH_STATE_REQUEST_COMPLETION_ML) \ + _(XrWorldMeshBufferRecommendedSizeInfoML, XR_TYPE_WORLD_MESH_BUFFER_RECOMMENDED_SIZE_INFO_ML) \ + _(XrWorldMeshBufferSizeML, XR_TYPE_WORLD_MESH_BUFFER_SIZE_ML) \ + _(XrWorldMeshBufferML, XR_TYPE_WORLD_MESH_BUFFER_ML) \ + _(XrWorldMeshBlockRequestML, XR_TYPE_WORLD_MESH_BLOCK_REQUEST_ML) \ + _(XrWorldMeshGetInfoML, XR_TYPE_WORLD_MESH_GET_INFO_ML) \ + _(XrWorldMeshBlockML, XR_TYPE_WORLD_MESH_BLOCK_ML) \ + _(XrWorldMeshRequestCompletionInfoML, XR_TYPE_WORLD_MESH_REQUEST_COMPLETION_INFO_ML) \ + _(XrWorldMeshRequestCompletionML, XR_TYPE_WORLD_MESH_REQUEST_COMPLETION_ML) \ #if defined(XR_USE_GRAPHICS_API_D3D11) @@ -5108,6 +5568,18 @@ XR_ENUM_STR(XrResult); #define XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_D3D12(_) #endif +#if defined(XR_USE_GRAPHICS_API_METAL) +/// Implementation detail of XR_LIST_STRUCTURE_TYPES() +/// Structure types available only when XR_USE_GRAPHICS_API_METAL is defined +#define XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_METAL(_) \ + _(XrGraphicsBindingMetalKHR, XR_TYPE_GRAPHICS_BINDING_METAL_KHR) \ + _(XrSwapchainImageMetalKHR, XR_TYPE_SWAPCHAIN_IMAGE_METAL_KHR) \ + _(XrGraphicsRequirementsMetalKHR, XR_TYPE_GRAPHICS_REQUIREMENTS_METAL_KHR) \ + +#else +#define XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_METAL(_) +#endif + #if defined(XR_USE_GRAPHICS_API_OPENGL) /// Implementation detail of XR_LIST_STRUCTURE_TYPES() /// Structure types available only when XR_USE_GRAPHICS_API_OPENGL is defined @@ -5264,6 +5736,7 @@ XR_ENUM_STR(XrResult); _(XR_KHR_vulkan_enable, 26) \ _(XR_KHR_D3D11_enable, 28) \ _(XR_KHR_D3D12_enable, 29) \ + _(XR_KHR_metal_enable, 30) \ _(XR_EXT_eye_gaze_interaction, 31) \ _(XR_KHR_visibility_mask, 32) \ _(XR_EXTX_overlay, 34) \ @@ -5340,6 +5813,8 @@ XR_ENUM_STR(XrResult); _(XR_ML_compat, 138) \ _(XR_ML_marker_understanding, 139) \ _(XR_ML_localization_map, 140) \ + _(XR_ML_spatial_anchors, 141) \ + _(XR_ML_spatial_anchors_storage, 142) \ _(XR_MSFT_spatial_anchor_persistence, 143) \ _(XR_MSFT_scene_marker, 148) \ _(XR_ULTRALEAP_hand_tracking_forearm, 150) \ @@ -5390,6 +5865,7 @@ XR_ENUM_STR(XrResult); _(XR_HTC_passthrough, 318) \ _(XR_HTC_foveation, 319) \ _(XR_HTC_anchor, 320) \ + _(XR_HTC_body_tracking, 321) \ _(XR_EXT_active_action_set_priority, 374) \ _(XR_MNDX_force_feedback_curl, 376) \ _(XR_BD_controller_interaction, 385) \ @@ -5401,6 +5877,9 @@ XR_ENUM_STR(XrResult); _(XR_EXT_user_presence, 471) \ _(XR_KHR_locate_spaces, 472) \ _(XR_ML_user_calibration, 473) \ + _(XR_ML_system_notifications, 474) \ + _(XR_ML_world_mesh_detection, 475) \ + _(XR_ML_view_configuration_depth_range_change, 484) \ _(XR_YVR_controller_interaction, 498) \ _(XR_EXT_composition_layer_inverted_alpha, 555) \ _(XR_KHR_maintenance1, 711) \ @@ -5546,6 +6025,14 @@ XR_ENUM_STR(XrResult); _(GetD3D12GraphicsRequirementsKHR, KHR_D3D12_enable) \ +/// For every function defined by XR_KHR_metal_enable in this version of the spec, +/// calls your macro with the function name and extension name. +/// Trims the leading `xr` from the function name and the leading `XR_` from the feature name, +/// because it is easy to add back but impossible to remove with the preprocessor. +#define XR_LIST_FUNCTIONS_XR_KHR_metal_enable(_) \ + _(GetMetalGraphicsRequirementsKHR, KHR_metal_enable) \ + + /// For every function defined by XR_KHR_visibility_mask in this version of the spec, /// calls your macro with the function name and extension name. /// Trims the leading `xr` from the function name and the leading `XR_` from the feature name, @@ -5932,6 +6419,33 @@ XR_ENUM_STR(XrResult); _(GetExportedLocalizationMapDataML, ML_localization_map) \ +/// For every function defined by XR_ML_spatial_anchors in this version of the spec, +/// calls your macro with the function name and extension name. +/// Trims the leading `xr` from the function name and the leading `XR_` from the feature name, +/// because it is easy to add back but impossible to remove with the preprocessor. +#define XR_LIST_FUNCTIONS_XR_ML_spatial_anchors(_) \ + _(CreateSpatialAnchorsAsyncML, ML_spatial_anchors) \ + _(CreateSpatialAnchorsCompleteML, ML_spatial_anchors) \ + _(GetSpatialAnchorStateML, ML_spatial_anchors) \ + + +/// For every function defined by XR_ML_spatial_anchors_storage in this version of the spec, +/// calls your macro with the function name and extension name. +/// Trims the leading `xr` from the function name and the leading `XR_` from the feature name, +/// because it is easy to add back but impossible to remove with the preprocessor. +#define XR_LIST_FUNCTIONS_XR_ML_spatial_anchors_storage(_) \ + _(CreateSpatialAnchorsStorageML, ML_spatial_anchors_storage) \ + _(DestroySpatialAnchorsStorageML, ML_spatial_anchors_storage) \ + _(QuerySpatialAnchorsAsyncML, ML_spatial_anchors_storage) \ + _(QuerySpatialAnchorsCompleteML, ML_spatial_anchors_storage) \ + _(PublishSpatialAnchorsAsyncML, ML_spatial_anchors_storage) \ + _(PublishSpatialAnchorsCompleteML, ML_spatial_anchors_storage) \ + _(DeleteSpatialAnchorsAsyncML, ML_spatial_anchors_storage) \ + _(DeleteSpatialAnchorsCompleteML, ML_spatial_anchors_storage) \ + _(UpdateSpatialAnchorsExpirationAsyncML, ML_spatial_anchors_storage) \ + _(UpdateSpatialAnchorsExpirationCompleteML, ML_spatial_anchors_storage) \ + + /// For every function defined by XR_MSFT_spatial_anchor_persistence in this version of the spec, /// calls your macro with the function name and extension name. /// Trims the leading `xr` from the function name and the leading `XR_` from the feature name, @@ -6220,6 +6734,17 @@ XR_ENUM_STR(XrResult); _(GetSpatialAnchorNameHTC, HTC_anchor) \ +/// For every function defined by XR_HTC_body_tracking in this version of the spec, +/// calls your macro with the function name and extension name. +/// Trims the leading `xr` from the function name and the leading `XR_` from the feature name, +/// because it is easy to add back but impossible to remove with the preprocessor. +#define XR_LIST_FUNCTIONS_XR_HTC_body_tracking(_) \ + _(CreateBodyTrackerHTC, HTC_body_tracking) \ + _(DestroyBodyTrackerHTC, HTC_body_tracking) \ + _(LocateBodyJointsHTC, HTC_body_tracking) \ + _(GetBodySkeletonHTC, HTC_body_tracking) \ + + /// For every function defined by XR_MNDX_force_feedback_curl in this version of the spec, /// calls your macro with the function name and extension name. /// Trims the leading `xr` from the function name and the leading `XR_` from the feature name, @@ -6258,6 +6783,30 @@ XR_ENUM_STR(XrResult); _(EnableUserCalibrationEventsML, ML_user_calibration) \ +/// For every function defined by XR_ML_system_notifications in this version of the spec, +/// calls your macro with the function name and extension name. +/// Trims the leading `xr` from the function name and the leading `XR_` from the feature name, +/// because it is easy to add back but impossible to remove with the preprocessor. +#define XR_LIST_FUNCTIONS_XR_ML_system_notifications(_) \ + _(SetSystemNotificationsML, ML_system_notifications) \ + + +/// For every function defined by XR_ML_world_mesh_detection in this version of the spec, +/// calls your macro with the function name and extension name. +/// Trims the leading `xr` from the function name and the leading `XR_` from the feature name, +/// because it is easy to add back but impossible to remove with the preprocessor. +#define XR_LIST_FUNCTIONS_XR_ML_world_mesh_detection(_) \ + _(CreateWorldMeshDetectorML, ML_world_mesh_detection) \ + _(DestroyWorldMeshDetectorML, ML_world_mesh_detection) \ + _(RequestWorldMeshStateAsyncML, ML_world_mesh_detection) \ + _(RequestWorldMeshStateCompleteML, ML_world_mesh_detection) \ + _(GetWorldMeshBufferRecommendSizeML, ML_world_mesh_detection) \ + _(AllocateWorldMeshBufferML, ML_world_mesh_detection) \ + _(FreeWorldMeshBufferML, ML_world_mesh_detection) \ + _(RequestWorldMeshAsyncML, ML_world_mesh_detection) \ + _(RequestWorldMeshCompleteML, ML_world_mesh_detection) \ + + #endif diff --git a/thirdparty/openxr/include/openxr/openxr_reflection_parent_structs.h b/thirdparty/openxr/include/openxr/openxr_reflection_parent_structs.h index 50466abc1b..bffab47cc5 100644 --- a/thirdparty/openxr/include/openxr/openxr_reflection_parent_structs.h +++ b/thirdparty/openxr/include/openxr/openxr_reflection_parent_structs.h @@ -238,6 +238,53 @@ This file contains expansion macros (X Macros) for OpenXR structures that have a +/// Like XR_LIST_ALL_STRUCTURE_TYPES, but only includes types whose parent struct type is XrSpatialAnchorsCreateInfoBaseHeaderML +#define XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSpatialAnchorsCreateInfoBaseHeaderML(_avail, _unavail) \ + _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSpatialAnchorsCreateInfoBaseHeaderML_CORE(_avail, _unavail) \ + + +// Implementation detail of XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSpatialAnchorsCreateInfoBaseHeaderML() +#define _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSpatialAnchorsCreateInfoBaseHeaderML_CORE(_avail, _unavail) \ + _avail(XrSpatialAnchorsCreateInfoFromPoseML, XR_TYPE_SPATIAL_ANCHORS_CREATE_INFO_FROM_POSE_ML) \ + _avail(XrSpatialAnchorsCreateInfoFromUuidsML, XR_TYPE_SPATIAL_ANCHORS_CREATE_INFO_FROM_UUIDS_ML) \ + + + + + +/// Like XR_LIST_ALL_STRUCTURE_TYPES, but only includes types whose parent struct type is XrFutureCompletionBaseHeaderEXT +#define XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrFutureCompletionBaseHeaderEXT(_avail, _unavail) \ + _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrFutureCompletionBaseHeaderEXT_CORE(_avail, _unavail) \ + + +// Implementation detail of XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrFutureCompletionBaseHeaderEXT() +#define _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrFutureCompletionBaseHeaderEXT_CORE(_avail, _unavail) \ + _avail(XrCreateSpatialAnchorsCompletionML, XR_TYPE_CREATE_SPATIAL_ANCHORS_COMPLETION_ML) \ + _avail(XrSpatialAnchorsQueryCompletionML, XR_TYPE_SPATIAL_ANCHORS_QUERY_COMPLETION_ML) \ + _avail(XrSpatialAnchorsPublishCompletionML, XR_TYPE_SPATIAL_ANCHORS_PUBLISH_COMPLETION_ML) \ + _avail(XrSpatialAnchorsDeleteCompletionML, XR_TYPE_SPATIAL_ANCHORS_DELETE_COMPLETION_ML) \ + _avail(XrSpatialAnchorsUpdateExpirationCompletionML, XR_TYPE_SPATIAL_ANCHORS_UPDATE_EXPIRATION_COMPLETION_ML) \ + _avail(XrFutureCompletionEXT, XR_TYPE_FUTURE_COMPLETION_EXT) \ + _avail(XrWorldMeshStateRequestCompletionML, XR_TYPE_WORLD_MESH_STATE_REQUEST_COMPLETION_ML) \ + _avail(XrWorldMeshRequestCompletionML, XR_TYPE_WORLD_MESH_REQUEST_COMPLETION_ML) \ + + + + + +/// Like XR_LIST_ALL_STRUCTURE_TYPES, but only includes types whose parent struct type is XrSpatialAnchorsQueryInfoBaseHeaderML +#define XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSpatialAnchorsQueryInfoBaseHeaderML(_avail, _unavail) \ + _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSpatialAnchorsQueryInfoBaseHeaderML_CORE(_avail, _unavail) \ + + +// Implementation detail of XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSpatialAnchorsQueryInfoBaseHeaderML() +#define _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSpatialAnchorsQueryInfoBaseHeaderML_CORE(_avail, _unavail) \ + _avail(XrSpatialAnchorsQueryInfoRadiusML, XR_TYPE_SPATIAL_ANCHORS_QUERY_INFO_RADIUS_ML) \ + + + + + /// Like XR_LIST_ALL_STRUCTURE_TYPES, but only includes types whose parent struct type is XrSpaceQueryInfoBaseHeaderFB #define XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSpaceQueryInfoBaseHeaderFB(_avail, _unavail) \ _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSpaceQueryInfoBaseHeaderFB_CORE(_avail, _unavail) \ @@ -265,18 +312,5 @@ This file contains expansion macros (X Macros) for OpenXR structures that have a -/// Like XR_LIST_ALL_STRUCTURE_TYPES, but only includes types whose parent struct type is XrFutureCompletionBaseHeaderEXT -#define XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrFutureCompletionBaseHeaderEXT(_avail, _unavail) \ - _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrFutureCompletionBaseHeaderEXT_CORE(_avail, _unavail) \ - - -// Implementation detail of XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrFutureCompletionBaseHeaderEXT() -#define _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrFutureCompletionBaseHeaderEXT_CORE(_avail, _unavail) \ - _avail(XrFutureCompletionEXT, XR_TYPE_FUTURE_COMPLETION_EXT) \ - - - - - #endif diff --git a/thirdparty/openxr/include/openxr/openxr_reflection_structs.h b/thirdparty/openxr/include/openxr/openxr_reflection_structs.h index e87e55b560..b1ab8e7779 100644 --- a/thirdparty/openxr/include/openxr/openxr_reflection_structs.h +++ b/thirdparty/openxr/include/openxr/openxr_reflection_structs.h @@ -27,6 +27,7 @@ This file contains expansion macros (X Macros) for OpenXR structures. _impl_XR_LIST_ALL_STRUCTURE_TYPES_CORE(_avail, _unavail) \ _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_D3D11(_avail, _unavail) \ _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_D3D12(_avail, _unavail) \ + _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_METAL(_avail, _unavail) \ _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL(_avail, _unavail) \ _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL_XR_USE_PLATFORM_WAYLAND(_avail, _unavail) \ _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL_XR_USE_PLATFORM_WIN32(_avail, _unavail) \ @@ -242,6 +243,22 @@ This file contains expansion macros (X Macros) for OpenXR structures. _avail(XrMapLocalizationRequestInfoML, XR_TYPE_MAP_LOCALIZATION_REQUEST_INFO_ML) \ _avail(XrLocalizationMapImportInfoML, XR_TYPE_LOCALIZATION_MAP_IMPORT_INFO_ML) \ _avail(XrLocalizationEnableEventsInfoML, XR_TYPE_LOCALIZATION_ENABLE_EVENTS_INFO_ML) \ + _avail(XrSpatialAnchorsCreateInfoFromPoseML, XR_TYPE_SPATIAL_ANCHORS_CREATE_INFO_FROM_POSE_ML) \ + _avail(XrCreateSpatialAnchorsCompletionML, XR_TYPE_CREATE_SPATIAL_ANCHORS_COMPLETION_ML) \ + _avail(XrSpatialAnchorStateML, XR_TYPE_SPATIAL_ANCHOR_STATE_ML) \ + _avail(XrSpatialAnchorsCreateStorageInfoML, XR_TYPE_SPATIAL_ANCHORS_CREATE_STORAGE_INFO_ML) \ + _avail(XrSpatialAnchorsQueryInfoRadiusML, XR_TYPE_SPATIAL_ANCHORS_QUERY_INFO_RADIUS_ML) \ + _avail(XrSpatialAnchorsQueryCompletionML, XR_TYPE_SPATIAL_ANCHORS_QUERY_COMPLETION_ML) \ + _avail(XrSpatialAnchorsCreateInfoFromUuidsML, XR_TYPE_SPATIAL_ANCHORS_CREATE_INFO_FROM_UUIDS_ML) \ + _avail(XrSpatialAnchorsPublishInfoML, XR_TYPE_SPATIAL_ANCHORS_PUBLISH_INFO_ML) \ + _avail(XrSpatialAnchorsPublishCompletionML, XR_TYPE_SPATIAL_ANCHORS_PUBLISH_COMPLETION_ML) \ + _avail(XrSpatialAnchorsDeleteInfoML, XR_TYPE_SPATIAL_ANCHORS_DELETE_INFO_ML) \ + _avail(XrSpatialAnchorsDeleteCompletionML, XR_TYPE_SPATIAL_ANCHORS_DELETE_COMPLETION_ML) \ + _avail(XrSpatialAnchorsUpdateExpirationInfoML, XR_TYPE_SPATIAL_ANCHORS_UPDATE_EXPIRATION_INFO_ML) \ + _avail(XrSpatialAnchorsUpdateExpirationCompletionML, XR_TYPE_SPATIAL_ANCHORS_UPDATE_EXPIRATION_COMPLETION_ML) \ + _avail(XrSpatialAnchorsPublishCompletionDetailsML, XR_TYPE_SPATIAL_ANCHORS_PUBLISH_COMPLETION_DETAILS_ML) \ + _avail(XrSpatialAnchorsDeleteCompletionDetailsML, XR_TYPE_SPATIAL_ANCHORS_DELETE_COMPLETION_DETAILS_ML) \ + _avail(XrSpatialAnchorsUpdateExpirationCompletionDetailsML, XR_TYPE_SPATIAL_ANCHORS_UPDATE_EXPIRATION_COMPLETION_DETAILS_ML) \ _avail(XrSpatialAnchorPersistenceInfoMSFT, XR_TYPE_SPATIAL_ANCHOR_PERSISTENCE_INFO_MSFT) \ _avail(XrSpatialAnchorFromPersistedAnchorCreateInfoMSFT, XR_TYPE_SPATIAL_ANCHOR_FROM_PERSISTED_ANCHOR_CREATE_INFO_MSFT) \ _avail(XrSceneMarkersMSFT, XR_TYPE_SCENE_MARKERS_MSFT) \ @@ -341,6 +358,11 @@ This file contains expansion macros (X Macros) for OpenXR structures. _avail(XrFoveationCustomModeInfoHTC, XR_TYPE_FOVEATION_CUSTOM_MODE_INFO_HTC) \ _avail(XrSystemAnchorPropertiesHTC, XR_TYPE_SYSTEM_ANCHOR_PROPERTIES_HTC) \ _avail(XrSpatialAnchorCreateInfoHTC, XR_TYPE_SPATIAL_ANCHOR_CREATE_INFO_HTC) \ + _avail(XrSystemBodyTrackingPropertiesHTC, XR_TYPE_SYSTEM_BODY_TRACKING_PROPERTIES_HTC) \ + _avail(XrBodyTrackerCreateInfoHTC, XR_TYPE_BODY_TRACKER_CREATE_INFO_HTC) \ + _avail(XrBodyJointsLocateInfoHTC, XR_TYPE_BODY_JOINTS_LOCATE_INFO_HTC) \ + _avail(XrBodyJointLocationsHTC, XR_TYPE_BODY_JOINT_LOCATIONS_HTC) \ + _avail(XrBodySkeletonHTC, XR_TYPE_BODY_SKELETON_HTC) \ _avail(XrActiveActionSetPrioritiesEXT, XR_TYPE_ACTIVE_ACTION_SET_PRIORITIES_EXT) \ _avail(XrSystemForceFeedbackCurlPropertiesMNDX, XR_TYPE_SYSTEM_FORCE_FEEDBACK_CURL_PROPERTIES_MNDX) \ _avail(XrForceFeedbackCurlApplyLocationsMNDX, XR_TYPE_FORCE_FEEDBACK_CURL_APPLY_LOCATIONS_MNDX) \ @@ -362,6 +384,19 @@ This file contains expansion macros (X Macros) for OpenXR structures. _avail(XrEventDataHeadsetFitChangedML, XR_TYPE_EVENT_DATA_HEADSET_FIT_CHANGED_ML) \ _avail(XrEventDataEyeCalibrationChangedML, XR_TYPE_EVENT_DATA_EYE_CALIBRATION_CHANGED_ML) \ _avail(XrUserCalibrationEnableEventsInfoML, XR_TYPE_USER_CALIBRATION_ENABLE_EVENTS_INFO_ML) \ + _avail(XrSystemNotificationsSetInfoML, XR_TYPE_SYSTEM_NOTIFICATIONS_SET_INFO_ML) \ + _avail(XrWorldMeshDetectorCreateInfoML, XR_TYPE_WORLD_MESH_DETECTOR_CREATE_INFO_ML) \ + _avail(XrWorldMeshBlockStateML, XR_TYPE_WORLD_MESH_BLOCK_STATE_ML) \ + _avail(XrWorldMeshStateRequestInfoML, XR_TYPE_WORLD_MESH_STATE_REQUEST_INFO_ML) \ + _avail(XrWorldMeshStateRequestCompletionML, XR_TYPE_WORLD_MESH_STATE_REQUEST_COMPLETION_ML) \ + _avail(XrWorldMeshBufferRecommendedSizeInfoML, XR_TYPE_WORLD_MESH_BUFFER_RECOMMENDED_SIZE_INFO_ML) \ + _avail(XrWorldMeshBufferSizeML, XR_TYPE_WORLD_MESH_BUFFER_SIZE_ML) \ + _avail(XrWorldMeshBufferML, XR_TYPE_WORLD_MESH_BUFFER_ML) \ + _avail(XrWorldMeshBlockRequestML, XR_TYPE_WORLD_MESH_BLOCK_REQUEST_ML) \ + _avail(XrWorldMeshGetInfoML, XR_TYPE_WORLD_MESH_GET_INFO_ML) \ + _avail(XrWorldMeshBlockML, XR_TYPE_WORLD_MESH_BLOCK_ML) \ + _avail(XrWorldMeshRequestCompletionInfoML, XR_TYPE_WORLD_MESH_REQUEST_COMPLETION_INFO_ML) \ + _avail(XrWorldMeshRequestCompletionML, XR_TYPE_WORLD_MESH_REQUEST_COMPLETION_ML) \ #if defined(XR_USE_GRAPHICS_API_D3D11) @@ -392,6 +427,20 @@ This file contains expansion macros (X Macros) for OpenXR structures. #endif +#if defined(XR_USE_GRAPHICS_API_METAL) +#define _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_METAL(_avail, _unavail) \ + _avail(XrGraphicsBindingMetalKHR, XR_TYPE_GRAPHICS_BINDING_METAL_KHR) \ + _avail(XrSwapchainImageMetalKHR, XR_TYPE_SWAPCHAIN_IMAGE_METAL_KHR) \ + _avail(XrGraphicsRequirementsMetalKHR, XR_TYPE_GRAPHICS_REQUIREMENTS_METAL_KHR) \ + +#else +#define _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_METAL(_avail, _unavail) \ + _unavail(XrGraphicsBindingMetalKHR, XR_TYPE_GRAPHICS_BINDING_METAL_KHR) \ + _unavail(XrSwapchainImageMetalKHR, XR_TYPE_SWAPCHAIN_IMAGE_METAL_KHR) \ + _unavail(XrGraphicsRequirementsMetalKHR, XR_TYPE_GRAPHICS_REQUIREMENTS_METAL_KHR) \ + +#endif + #if defined(XR_USE_GRAPHICS_API_OPENGL) #define _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL(_avail, _unavail) \ _avail(XrSwapchainImageOpenGLKHR, XR_TYPE_SWAPCHAIN_IMAGE_OPENGL_KHR) \ diff --git a/thirdparty/openxr/src/common/platform_utils.hpp b/thirdparty/openxr/src/common/platform_utils.hpp index d047c17d9d..19cd41cbb2 100644 --- a/thirdparty/openxr/src/common/platform_utils.hpp +++ b/thirdparty/openxr/src/common/platform_utils.hpp @@ -91,21 +91,22 @@ namespace detail { static inline char* ImplGetEnv(const char* name) { return getenv(name); } +// clang-format off static inline char* ImplGetSecureEnv(const char* name) { #ifdef HAVE_SECURE_GETENV return secure_getenv(name); #elif defined(HAVE___SECURE_GETENV) return __secure_getenv(name); #else -// clang-format off #pragma message( \ "Warning: Falling back to non-secure getenv for environmental" \ "lookups! Consider updating to a different libc.") - // clang-format on return ImplGetEnv(name); #endif } +// clang-format on + } // namespace detail #endif // defined(XR_OS_LINUX) || defined(XR_OS_APPLE) diff --git a/thirdparty/openxr/src/common/xr_linear.h b/thirdparty/openxr/src/common/xr_linear.h index 2b295ed304..cc525d3357 100644 --- a/thirdparty/openxr/src/common/xr_linear.h +++ b/thirdparty/openxr/src/common/xr_linear.h @@ -134,7 +134,7 @@ static const XrColor4f XrColorCyan = {0.0f, 1.0f, 1.0f, 1.0f}; static const XrColor4f XrColorLightGrey = {0.7f, 0.7f, 0.7f, 1.0f}; static const XrColor4f XrColorDarkGrey = {0.3f, 0.3f, 0.3f, 1.0f}; -typedef enum GraphicsAPI { GRAPHICS_VULKAN, GRAPHICS_OPENGL, GRAPHICS_OPENGL_ES, GRAPHICS_D3D } GraphicsAPI; +typedef enum GraphicsAPI { GRAPHICS_VULKAN, GRAPHICS_OPENGL, GRAPHICS_OPENGL_ES, GRAPHICS_D3D, GRAPHICS_METAL } GraphicsAPI; // Column-major, pre-multiplied. This type does not exist in the OpenXR API and is provided for convenience. typedef struct XrMatrix4x4f { diff --git a/thirdparty/openxr/src/loader/android_utilities.cpp b/thirdparty/openxr/src/loader/android_utilities.cpp index 5c9b846b5a..1f7424b8e6 100644 --- a/thirdparty/openxr/src/loader/android_utilities.cpp +++ b/thirdparty/openxr/src/loader/android_utilities.cpp @@ -15,6 +15,7 @@ #include <openxr/openxr.h> +#include <dlfcn.h> #include <sstream> #include <vector> #include <android/log.h> @@ -82,7 +83,6 @@ static Uri makeContentUri(bool systemBroker, int majorVersion, const char *abi) .appendPath(abi) .appendPath(RUNTIMES_PATH) .appendPath(TABLE_PATH); - ContentUris::appendId(builder, 0); return builder.build(); } @@ -175,7 +175,6 @@ static inline jni::Array<std::string> makeArray(std::initializer_list<const char } return ret; } -static constexpr auto TAG = "OpenXR-Loader"; #if defined(__arm__) static constexpr auto ABI = "armeabi-v7l"; @@ -313,26 +312,41 @@ int getActiveRuntimeVirtualManifest(wrap::android::content::Context const &conte cursor.moveToFirst(); - auto filename = cursor.getString(cursor.getColumnIndex(active_runtime::Columns::SO_FILENAME)); - auto libDir = cursor.getString(cursor.getColumnIndex(active_runtime::Columns::NATIVE_LIB_DIR)); - auto packageName = cursor.getString(cursor.getColumnIndex(active_runtime::Columns::PACKAGE_NAME)); - - auto hasFunctions = cursor.getInt(cursor.getColumnIndex(active_runtime::Columns::HAS_FUNCTIONS)) == 1; - __android_log_print(ANDROID_LOG_INFO, TAG, "Got runtime: package: %s, so filename: %s, native lib dir: %s, has functions: %s", - packageName.c_str(), filename.c_str(), libDir.c_str(), (hasFunctions ? "yes" : "no")); + do { + auto filename = cursor.getString(cursor.getColumnIndex(active_runtime::Columns::SO_FILENAME)); + auto libDir = cursor.getString(cursor.getColumnIndex(active_runtime::Columns::NATIVE_LIB_DIR)); + auto packageName = cursor.getString(cursor.getColumnIndex(active_runtime::Columns::PACKAGE_NAME)); + + auto hasFunctions = cursor.getInt(cursor.getColumnIndex(active_runtime::Columns::HAS_FUNCTIONS)) == 1; + ALOGI("Got runtime: package: %s, so filename: %s, native lib dir: %s, has functions: %s", packageName.c_str(), + filename.c_str(), libDir.c_str(), (hasFunctions ? "yes" : "no")); + + auto lib_path = libDir + "/" + filename; + auto *lib = dlopen(lib_path.c_str(), RTLD_LAZY | RTLD_LOCAL); + if (lib) { + // we found a runtime that we can dlopen, use it. + dlclose(lib); + + JsonManifestBuilder builder{"runtime", lib_path}; + if (hasFunctions) { + int result = populateFunctions(context, systemBroker, packageName, builder); + if (result != 0) { + ALOGW("Unable to populate functions from runtime: %s, checking for more records...", lib_path.c_str()); + continue; + } + } + virtualManifest = builder.build(); + cursor.close(); + return 0; + } + // this runtime was not accessible, see if the broker has more runtimes on + // offer. + ALOGV("Unable to open broker provided runtime at %s, checking for more records...", lib_path.c_str()); + } while (cursor.moveToNext()); - auto lib_path = libDir + "/" + filename; + ALOGE("Unable to open any of the broker provided runtimes."); cursor.close(); - - JsonManifestBuilder builder{"runtime", lib_path}; - if (hasFunctions) { - int result = populateFunctions(context, systemBroker, packageName, builder); - if (result != 0) { - return result; - } - } - virtualManifest = builder.build(); - return 0; + return -1; } } // namespace openxr_android diff --git a/thirdparty/openxr/src/loader/loader_core.cpp b/thirdparty/openxr/src/loader/loader_core.cpp index 8bf2609a08..a0d81b28dc 100644 --- a/thirdparty/openxr/src/loader/loader_core.cpp +++ b/thirdparty/openxr/src/loader/loader_core.cpp @@ -334,7 +334,7 @@ static XRAPI_ATTR XrResult XRAPI_CALL LoaderXrDestroyInstance(XrInstance instanc return result; } - const std::unique_ptr<XrGeneratedDispatchTable> &dispatch_table = loader_instance->DispatchTable(); + const std::unique_ptr<XrGeneratedDispatchTableCore> &dispatch_table = loader_instance->DispatchTable(); // If we allocated a default debug utils messenger, free it XrDebugUtilsMessengerEXT messenger = loader_instance->DefaultDebugUtilsMessenger(); @@ -546,7 +546,7 @@ LoaderTrampolineSessionBeginDebugUtilsLabelRegionEXT(XrSession session, const Xr return result; } LoaderLogger::GetInstance().BeginLabelRegion(session, labelInfo); - const std::unique_ptr<XrGeneratedDispatchTable> &dispatch_table = loader_instance->DispatchTable(); + const std::unique_ptr<XrGeneratedDispatchTableCore> &dispatch_table = loader_instance->DispatchTable(); if (nullptr != dispatch_table->SessionBeginDebugUtilsLabelRegionEXT) { return dispatch_table->SessionBeginDebugUtilsLabelRegionEXT(session, labelInfo); } @@ -567,7 +567,7 @@ static XRAPI_ATTR XrResult XRAPI_CALL LoaderTrampolineSessionEndDebugUtilsLabelR } LoaderLogger::GetInstance().EndLabelRegion(session); - const std::unique_ptr<XrGeneratedDispatchTable> &dispatch_table = loader_instance->DispatchTable(); + const std::unique_ptr<XrGeneratedDispatchTableCore> &dispatch_table = loader_instance->DispatchTable(); if (nullptr != dispatch_table->SessionEndDebugUtilsLabelRegionEXT) { return dispatch_table->SessionEndDebugUtilsLabelRegionEXT(session); } @@ -597,7 +597,7 @@ LoaderTrampolineSessionInsertDebugUtilsLabelEXT(XrSession session, const XrDebug LoaderLogger::GetInstance().InsertLabel(session, labelInfo); - const std::unique_ptr<XrGeneratedDispatchTable> &dispatch_table = loader_instance->DispatchTable(); + const std::unique_ptr<XrGeneratedDispatchTableCore> &dispatch_table = loader_instance->DispatchTable(); if (nullptr != dispatch_table->SessionInsertDebugUtilsLabelEXT) { return dispatch_table->SessionInsertDebugUtilsLabelEXT(session, labelInfo); } @@ -643,7 +643,7 @@ XRAPI_ATTR XrResult XRAPI_CALL LoaderXrTermCreateDebugUtilsMessengerEXT(XrInstan "xrCreateDebugUtilsMessengerEXT", "invalid messenger pointer"); return XR_ERROR_VALIDATION_FAILURE; } - const XrGeneratedDispatchTable *dispatch_table = RuntimeInterface::GetDispatchTable(instance); + const XrGeneratedDispatchTableCore *dispatch_table = RuntimeInterface::GetDispatchTable(instance); XrResult result = XR_SUCCESS; // This extension is supported entirely by the loader which means the runtime may or may not support it. if (nullptr != dispatch_table->CreateDebugUtilsMessengerEXT) { @@ -664,7 +664,7 @@ XRLOADER_ABI_CATCH_FALLBACK XRAPI_ATTR XrResult XRAPI_CALL LoaderXrTermDestroyDebugUtilsMessengerEXT(XrDebugUtilsMessengerEXT messenger) XRLOADER_ABI_TRY { LoaderLogger::LogVerboseMessage("xrDestroyDebugUtilsMessengerEXT", "Entering loader terminator"); - const XrGeneratedDispatchTable *dispatch_table = RuntimeInterface::GetDebugUtilsMessengerDispatchTable(messenger); + const XrGeneratedDispatchTableCore *dispatch_table = RuntimeInterface::GetDebugUtilsMessengerDispatchTable(messenger); XrResult result = XR_SUCCESS; LoaderLogger::GetInstance().RemoveLogRecorder(MakeHandleGeneric(messenger)); RuntimeInterface::GetRuntime().ForgetDebugMessenger(messenger); @@ -684,7 +684,7 @@ XRAPI_ATTR XrResult XRAPI_CALL LoaderXrTermSubmitDebugUtilsMessageEXT( XrInstance instance, XrDebugUtilsMessageSeverityFlagsEXT messageSeverity, XrDebugUtilsMessageTypeFlagsEXT messageTypes, const XrDebugUtilsMessengerCallbackDataEXT *callbackData) XRLOADER_ABI_TRY { LoaderLogger::LogVerboseMessage("xrSubmitDebugUtilsMessageEXT", "Entering loader terminator"); - const XrGeneratedDispatchTable *dispatch_table = RuntimeInterface::GetDispatchTable(instance); + const XrGeneratedDispatchTableCore *dispatch_table = RuntimeInterface::GetDispatchTable(instance); XrResult result = XR_SUCCESS; if (nullptr != dispatch_table->SubmitDebugUtilsMessageEXT) { result = dispatch_table->SubmitDebugUtilsMessageEXT(instance, messageSeverity, messageTypes, callbackData); @@ -701,7 +701,7 @@ XRLOADER_ABI_CATCH_FALLBACK XRAPI_ATTR XrResult XRAPI_CALL LoaderXrTermSetDebugUtilsObjectNameEXT(XrInstance instance, const XrDebugUtilsObjectNameInfoEXT *nameInfo) XRLOADER_ABI_TRY { LoaderLogger::LogVerboseMessage("xrSetDebugUtilsObjectNameEXT", "Entering loader terminator"); - const XrGeneratedDispatchTable *dispatch_table = RuntimeInterface::GetDispatchTable(instance); + const XrGeneratedDispatchTableCore *dispatch_table = RuntimeInterface::GetDispatchTable(instance); XrResult result = XR_SUCCESS; if (nullptr != dispatch_table->SetDebugUtilsObjectNameEXT) { result = dispatch_table->SetDebugUtilsObjectNameEXT(instance, nameInfo); diff --git a/thirdparty/openxr/src/loader/loader_instance.cpp b/thirdparty/openxr/src/loader/loader_instance.cpp index f18230087f..09521ecf47 100644 --- a/thirdparty/openxr/src/loader/loader_instance.cpp +++ b/thirdparty/openxr/src/loader/loader_instance.cpp @@ -278,12 +278,12 @@ LoaderInstance::LoaderInstance(XrInstance instance, const XrInstanceCreateInfo* : _runtime_instance(instance), _topmost_gipa(topmost_gipa), _api_layer_interfaces(std::move(api_layer_interfaces)), - _dispatch_table(new XrGeneratedDispatchTable{}) { + _dispatch_table(new XrGeneratedDispatchTableCore{}) { for (uint32_t ext = 0; ext < create_info->enabledExtensionCount; ++ext) { _enabled_extensions.push_back(create_info->enabledExtensionNames[ext]); } - GeneratedXrPopulateDispatchTable(_dispatch_table.get(), instance, topmost_gipa); + GeneratedXrPopulateDispatchTableCore(_dispatch_table.get(), instance, topmost_gipa); } LoaderInstance::~LoaderInstance() { diff --git a/thirdparty/openxr/src/loader/loader_instance.hpp b/thirdparty/openxr/src/loader/loader_instance.hpp index b99e6b047f..93cd5dc6a4 100644 --- a/thirdparty/openxr/src/loader/loader_instance.hpp +++ b/thirdparty/openxr/src/loader/loader_instance.hpp @@ -23,7 +23,7 @@ #include <vector> class ApiLayerInterface; -struct XrGeneratedDispatchTable; +struct XrGeneratedDispatchTableCore; class LoaderInstance; // Manage the single loader instance that is available. @@ -54,7 +54,7 @@ class LoaderInstance { virtual ~LoaderInstance(); XrInstance GetInstanceHandle() { return _runtime_instance; } - const std::unique_ptr<XrGeneratedDispatchTable>& DispatchTable() { return _dispatch_table; } + const std::unique_ptr<XrGeneratedDispatchTableCore>& DispatchTable() { return _dispatch_table; } std::vector<std::unique_ptr<ApiLayerInterface>>& LayerInterfaces() { return _api_layer_interfaces; } bool ExtensionIsEnabled(const std::string& extension); XrDebugUtilsMessengerEXT DefaultDebugUtilsMessenger() { return _messenger; } @@ -71,7 +71,7 @@ class LoaderInstance { std::vector<std::string> _enabled_extensions; std::vector<std::unique_ptr<ApiLayerInterface>> _api_layer_interfaces; - std::unique_ptr<XrGeneratedDispatchTable> _dispatch_table; + std::unique_ptr<XrGeneratedDispatchTableCore> _dispatch_table; // Internal debug messenger created during xrCreateInstance XrDebugUtilsMessengerEXT _messenger{XR_NULL_HANDLE}; }; diff --git a/thirdparty/openxr/src/loader/manifest_file.cpp b/thirdparty/openxr/src/loader/manifest_file.cpp index 4e3e5b4947..ca212d3435 100644 --- a/thirdparty/openxr/src/loader/manifest_file.cpp +++ b/thirdparty/openxr/src/loader/manifest_file.cpp @@ -75,11 +75,12 @@ static inline bool StringEndsWith(const std::string &value, const std::string &e } // If the file found is a manifest file name, add it to the out_files manifest list. -static void AddIfJson(const std::string &full_file, std::vector<std::string> &manifest_files) { +static bool AddIfJson(const std::string &full_file, std::vector<std::string> &manifest_files) { if (full_file.empty() || !StringEndsWith(full_file, ".json")) { - return; + return false; } manifest_files.push_back(full_file); + return true; } // Check the current path for any manifest files. If the provided search_path is a directory, look for @@ -381,7 +382,6 @@ static void ReadRuntimeDataFilesInRegistry(const std::string &runtime_registry_l if (ERROR_SUCCESS != open_value) { LoaderLogger::LogWarningMessage("", "ReadRuntimeDataFilesInRegistry - failed to open registry key " + full_registry_location); - return; } @@ -391,7 +391,23 @@ static void ReadRuntimeDataFilesInRegistry(const std::string &runtime_registry_l LoaderLogger::LogWarningMessage( "", "ReadRuntimeDataFilesInRegistry - failed to read registry value " + default_runtime_value_name); } else { - AddFilesInPath(wide_to_utf8(value_w), false, manifest_files); + // Not using AddFilesInPath here (as only api_layer manifest paths allow multiple + // separated paths) + // Small time-of-check vs time-of-use issue here but it mainly only affects the error message. + // It does not introduce a security defect. + std::string activeRuntimePath = wide_to_utf8(value_w); + if (FileSysUtilsIsRegularFile(activeRuntimePath)) { + // If the file exists, try to add it + std::string absolute_path; + FileSysUtilsGetAbsolutePath(activeRuntimePath, absolute_path); + if (!AddIfJson(absolute_path, manifest_files)) { + LoaderLogger::LogErrorMessage( + "", "ReadRuntimeDataFilesInRegistry - registry runtime path is not json " + activeRuntimePath); + } + } else { + LoaderLogger::LogErrorMessage( + "", "ReadRuntimeDataFilesInRegistry - registry runtime path does not exist " + activeRuntimePath); + } } RegCloseKey(hkey); @@ -757,8 +773,7 @@ void ApiLayerManifestFile::AddManifestFilesAndroid(const std::string &openxr_com } std::istringstream json_stream(std::string{buf, length}); - CreateIfValid(ManifestFileType::MANIFEST_TYPE_EXPLICIT_API_LAYER, filename, json_stream, - &ApiLayerManifestFile::LocateLibraryInAssets, manifest_files); + CreateIfValid(type, filename, json_stream, &ApiLayerManifestFile::LocateLibraryInAssets, manifest_files); } } #endif // defined(XR_USE_PLATFORM_ANDROID) && defined(XR_KHR_LOADER_INIT_SUPPORT) diff --git a/thirdparty/openxr/src/loader/runtime_interface.cpp b/thirdparty/openxr/src/loader/runtime_interface.cpp index a0296c738c..32feea6dde 100644 --- a/thirdparty/openxr/src/loader/runtime_interface.cpp +++ b/thirdparty/openxr/src/loader/runtime_interface.cpp @@ -126,6 +126,10 @@ XrResult RuntimeInterface::TryLoadingSingleRuntime(const std::string& openxr_com XrResult res = XR_ERROR_RUNTIME_FAILURE; if (nullptr != negotiate) { res = negotiate(&loader_info, &runtime_info); + } else { + std::string error_message = "RuntimeInterface::LoadRuntime failed to find negotiate function "; + error_message += function_name; + LoaderLogger::LogErrorMessage(openxr_command, error_message); } // If we supposedly succeeded, but got a nullptr for GetInstanceProcAddr // then something still went wrong, so return with an error. @@ -270,8 +274,8 @@ XrResult RuntimeInterface::GetInstanceProcAddr(XrInstance instance, const char* return GetInstance()->_get_instance_proc_addr(instance, name, function); } -const XrGeneratedDispatchTable* RuntimeInterface::GetDispatchTable(XrInstance instance) { - XrGeneratedDispatchTable* table = nullptr; +const XrGeneratedDispatchTableCore* RuntimeInterface::GetDispatchTable(XrInstance instance) { + XrGeneratedDispatchTableCore* table = nullptr; std::lock_guard<std::mutex> mlock(GetInstance()->_dispatch_table_mutex); auto it = GetInstance()->_dispatch_table_map.find(instance); if (it != GetInstance()->_dispatch_table_map.end()) { @@ -280,7 +284,7 @@ const XrGeneratedDispatchTable* RuntimeInterface::GetDispatchTable(XrInstance in return table; } -const XrGeneratedDispatchTable* RuntimeInterface::GetDebugUtilsMessengerDispatchTable(XrDebugUtilsMessengerEXT messenger) { +const XrGeneratedDispatchTableCore* RuntimeInterface::GetDebugUtilsMessengerDispatchTable(XrDebugUtilsMessengerEXT messenger) { XrInstance runtime_instance = XR_NULL_HANDLE; { std::lock_guard<std::mutex> mlock(GetInstance()->_messenger_to_instance_mutex); @@ -349,8 +353,8 @@ XrResult RuntimeInterface::CreateInstance(const XrInstanceCreateInfo* info, XrIn res = rt_xrCreateInstance(info, instance); if (XR_SUCCEEDED(res)) { create_succeeded = true; - std::unique_ptr<XrGeneratedDispatchTable> dispatch_table(new XrGeneratedDispatchTable()); - GeneratedXrPopulateDispatchTable(dispatch_table.get(), *instance, _get_instance_proc_addr); + std::unique_ptr<XrGeneratedDispatchTableCore> dispatch_table(new XrGeneratedDispatchTableCore()); + GeneratedXrPopulateDispatchTableCore(dispatch_table.get(), *instance, _get_instance_proc_addr); std::lock_guard<std::mutex> mlock(_dispatch_table_mutex); _dispatch_table_map[*instance] = std::move(dispatch_table); } diff --git a/thirdparty/openxr/src/loader/runtime_interface.hpp b/thirdparty/openxr/src/loader/runtime_interface.hpp index 093f8ba767..3d45b12946 100644 --- a/thirdparty/openxr/src/loader/runtime_interface.hpp +++ b/thirdparty/openxr/src/loader/runtime_interface.hpp @@ -24,7 +24,7 @@ class Value; } class RuntimeManifestFile; -struct XrGeneratedDispatchTable; +struct XrGeneratedDispatchTableCore; class RuntimeInterface { public: @@ -37,8 +37,8 @@ class RuntimeInterface { static XrResult GetInstanceProcAddr(XrInstance instance, const char* name, PFN_xrVoidFunction* function); // Get the direct dispatch table to this runtime, without API layers or loader terminators. - static const XrGeneratedDispatchTable* GetDispatchTable(XrInstance instance); - static const XrGeneratedDispatchTable* GetDebugUtilsMessengerDispatchTable(XrDebugUtilsMessengerEXT messenger); + static const XrGeneratedDispatchTableCore* GetDispatchTable(XrInstance instance); + static const XrGeneratedDispatchTableCore* GetDebugUtilsMessengerDispatchTable(XrDebugUtilsMessengerEXT messenger); void GetInstanceExtensionProperties(std::vector<XrExtensionProperties>& extension_properties); bool SupportsExtension(const std::string& extension_name); @@ -66,7 +66,7 @@ class RuntimeInterface { LoaderPlatformLibraryHandle _runtime_library; PFN_xrGetInstanceProcAddr _get_instance_proc_addr; - std::unordered_map<XrInstance, std::unique_ptr<XrGeneratedDispatchTable>> _dispatch_table_map; + std::unordered_map<XrInstance, std::unique_ptr<XrGeneratedDispatchTableCore>> _dispatch_table_map; std::mutex _dispatch_table_mutex; std::unordered_map<XrDebugUtilsMessengerEXT, XrInstance> _messenger_to_instance_map; std::mutex _messenger_to_instance_mutex; diff --git a/thirdparty/openxr/src/loader/xr_generated_loader.cpp b/thirdparty/openxr/src/loader/xr_generated_loader.cpp index 7bddbdc3ea..d7f1ed18c1 100644 --- a/thirdparty/openxr/src/loader/xr_generated_loader.cpp +++ b/thirdparty/openxr/src/loader/xr_generated_loader.cpp @@ -697,4 +697,17 @@ extern "C" LOADER_EXPORT XRAPI_ATTR XrResult XRAPI_CALL xrStopHapticFeedback( } XRLOADER_ABI_CATCH_FALLBACK +extern "C" LOADER_EXPORT XRAPI_ATTR XrResult XRAPI_CALL xrLocateSpaces( + XrSession session, + const XrSpacesLocateInfo* locateInfo, + XrSpaceLocations* spaceLocations) XRLOADER_ABI_TRY { + LoaderInstance* loader_instance; + XrResult result = ActiveLoaderInstance::Get(&loader_instance, "xrLocateSpaces"); + if (XR_SUCCEEDED(result)) { + result = loader_instance->DispatchTable()->LocateSpaces(session, locateInfo, spaceLocations); + } + return result; +} +XRLOADER_ABI_CATCH_FALLBACK + diff --git a/thirdparty/openxr/src/loader/xr_generated_loader.hpp b/thirdparty/openxr/src/loader/xr_generated_loader.hpp index 68a6b9470d..9a6c915421 100644 --- a/thirdparty/openxr/src/loader/xr_generated_loader.hpp +++ b/thirdparty/openxr/src/loader/xr_generated_loader.hpp @@ -245,6 +245,10 @@ extern "C" LOADER_EXPORT XRAPI_ATTR XrResult XRAPI_CALL xrApplyHapticFeedback( extern "C" LOADER_EXPORT XRAPI_ATTR XrResult XRAPI_CALL xrStopHapticFeedback( XrSession session, const XrHapticActionInfo* hapticActionInfo); +extern "C" LOADER_EXPORT XRAPI_ATTR XrResult XRAPI_CALL xrLocateSpaces( + XrSession session, + const XrSpacesLocateInfo* locateInfo, + XrSpaceLocations* spaceLocations); #ifdef __cplusplus } // extern "C" #endif diff --git a/thirdparty/openxr/src/xr_generated_dispatch_table_core.c b/thirdparty/openxr/src/xr_generated_dispatch_table_core.c index e73e8b2b95..aaf854704b 100644 --- a/thirdparty/openxr/src/xr_generated_dispatch_table_core.c +++ b/thirdparty/openxr/src/xr_generated_dispatch_table_core.c @@ -37,7 +37,7 @@ extern "C" { #endif // Helper function to populate an instance dispatch table -void GeneratedXrPopulateDispatchTable(struct XrGeneratedDispatchTable *table, +void GeneratedXrPopulateDispatchTableCore(struct XrGeneratedDispatchTableCore *table, XrInstance instance, PFN_xrGetInstanceProcAddr get_inst_proc_addr) { @@ -96,6 +96,9 @@ void GeneratedXrPopulateDispatchTable(struct XrGeneratedDispatchTable *table, (get_inst_proc_addr(instance, "xrApplyHapticFeedback", (PFN_xrVoidFunction*)&table->ApplyHapticFeedback)); (get_inst_proc_addr(instance, "xrStopHapticFeedback", (PFN_xrVoidFunction*)&table->StopHapticFeedback)); + // ---- Core 1.1 commands + (get_inst_proc_addr(instance, "xrLocateSpaces", (PFN_xrVoidFunction*)&table->LocateSpaces)); + // ---- XR_EXT_debug_utils extension commands (get_inst_proc_addr(instance, "xrSetDebugUtilsObjectNameEXT", (PFN_xrVoidFunction*)&table->SetDebugUtilsObjectNameEXT)); (get_inst_proc_addr(instance, "xrCreateDebugUtilsMessengerEXT", (PFN_xrVoidFunction*)&table->CreateDebugUtilsMessengerEXT)); diff --git a/thirdparty/openxr/src/xr_generated_dispatch_table_core.h b/thirdparty/openxr/src/xr_generated_dispatch_table_core.h index 5871231267..69abf10b93 100644 --- a/thirdparty/openxr/src/xr_generated_dispatch_table_core.h +++ b/thirdparty/openxr/src/xr_generated_dispatch_table_core.h @@ -38,7 +38,7 @@ extern "C" { #endif // Generated dispatch table -struct XrGeneratedDispatchTable { +struct XrGeneratedDispatchTableCore { // ---- Core 1.0 commands PFN_xrGetInstanceProcAddr GetInstanceProcAddr; @@ -97,6 +97,9 @@ struct XrGeneratedDispatchTable { PFN_xrApplyHapticFeedback ApplyHapticFeedback; PFN_xrStopHapticFeedback StopHapticFeedback; + // ---- Core 1.1 commands + PFN_xrLocateSpaces LocateSpaces; + // ---- XR_EXT_debug_utils extension commands PFN_xrSetDebugUtilsObjectNameEXT SetDebugUtilsObjectNameEXT; PFN_xrCreateDebugUtilsMessengerEXT CreateDebugUtilsMessengerEXT; @@ -109,7 +112,7 @@ struct XrGeneratedDispatchTable { // Prototype for dispatch table helper function -void GeneratedXrPopulateDispatchTable(struct XrGeneratedDispatchTable *table, +void GeneratedXrPopulateDispatchTableCore(struct XrGeneratedDispatchTableCore *table, XrInstance instance, PFN_xrGetInstanceProcAddr get_inst_proc_addr); diff --git a/thirdparty/squish/LICENSE.txt b/thirdparty/squish/LICENSE.txt deleted file mode 100644 index e491e36226..0000000000 --- a/thirdparty/squish/LICENSE.txt +++ /dev/null @@ -1,20 +0,0 @@ -Copyright (c) 2006 Simon Brown si@sjbrown.co.uk - -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. diff --git a/thirdparty/squish/alpha.cpp b/thirdparty/squish/alpha.cpp deleted file mode 100644 index 7039c1a3b8..0000000000 --- a/thirdparty/squish/alpha.cpp +++ /dev/null @@ -1,350 +0,0 @@ -/* ----------------------------------------------------------------------------- - - Copyright (c) 2006 Simon Brown si@sjbrown.co.uk - - 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 "alpha.h" - -#include <climits> -#include <algorithm> - -namespace squish { - -static int FloatToInt( float a, int limit ) -{ - // use ANSI round-to-zero behaviour to get round-to-nearest - int i = ( int )( a + 0.5f ); - - // clamp to the limit - if( i < 0 ) - i = 0; - else if( i > limit ) - i = limit; - - // done - return i; -} - -void CompressAlphaDxt3( u8 const* rgba, int mask, void* block ) -{ - u8* bytes = reinterpret_cast< u8* >( block ); - - // quantise and pack the alpha values pairwise - for( int i = 0; i < 8; ++i ) - { - // quantise down to 4 bits - float alpha1 = ( float )rgba[8*i + 3] * ( 15.0f/255.0f ); - float alpha2 = ( float )rgba[8*i + 7] * ( 15.0f/255.0f ); - int quant1 = FloatToInt( alpha1, 15 ); - int quant2 = FloatToInt( alpha2, 15 ); - - // set alpha to zero where masked - int bit1 = 1 << ( 2*i ); - int bit2 = 1 << ( 2*i + 1 ); - if( ( mask & bit1 ) == 0 ) - quant1 = 0; - if( ( mask & bit2 ) == 0 ) - quant2 = 0; - - // pack into the byte - bytes[i] = ( u8 )( quant1 | ( quant2 << 4 ) ); - } -} - -void DecompressAlphaDxt3( u8* rgba, void const* block ) -{ - u8 const* bytes = reinterpret_cast< u8 const* >( block ); - - // unpack the alpha values pairwise - for( int i = 0; i < 8; ++i ) - { - // quantise down to 4 bits - u8 quant = bytes[i]; - - // unpack the values - u8 lo = quant & 0x0f; - u8 hi = quant & 0xf0; - - // convert back up to bytes - rgba[8*i + 3] = lo | ( lo << 4 ); - rgba[8*i + 7] = hi | ( hi >> 4 ); - } -} - -static void FixRange( int& min, int& max, int steps ) -{ - if( max - min < steps ) - max = std::min( min + steps, 255 ); - if( max - min < steps ) - min = std::max( 0, max - steps ); -} - -static int FitCodes( u8 const* rgba, int mask, u8 const* codes, u8* indices ) -{ - // fit each alpha value to the codebook - int err = 0; - for( int i = 0; i < 16; ++i ) - { - // check this pixel is valid - int bit = 1 << i; - if( ( mask & bit ) == 0 ) - { - // use the first code - indices[i] = 0; - continue; - } - - // find the least error and corresponding index - int value = rgba[4*i + 3]; - int least = INT_MAX; - int index = 0; - for( int j = 0; j < 8; ++j ) - { - // get the squared error from this code - int dist = ( int )value - ( int )codes[j]; - dist *= dist; - - // compare with the best so far - if( dist < least ) - { - least = dist; - index = j; - } - } - - // save this index and accumulate the error - indices[i] = ( u8 )index; - err += least; - } - - // return the total error - return err; -} - -static void WriteAlphaBlock( int alpha0, int alpha1, u8 const* indices, void* block ) -{ - u8* bytes = reinterpret_cast< u8* >( block ); - - // write the first two bytes - bytes[0] = ( u8 )alpha0; - bytes[1] = ( u8 )alpha1; - - // pack the indices with 3 bits each - u8* dest = bytes + 2; - u8 const* src = indices; - for( int i = 0; i < 2; ++i ) - { - // pack 8 3-bit values - int value = 0; - for( int j = 0; j < 8; ++j ) - { - int index = *src++; - value |= ( index << 3*j ); - } - - // store in 3 bytes - for( int j = 0; j < 3; ++j ) - { - int byte = ( value >> 8*j ) & 0xff; - *dest++ = ( u8 )byte; - } - } -} - -static void WriteAlphaBlock5( int alpha0, int alpha1, u8 const* indices, void* block ) -{ - // check the relative values of the endpoints - if( alpha0 > alpha1 ) - { - // swap the indices - u8 swapped[16]; - for( int i = 0; i < 16; ++i ) - { - u8 index = indices[i]; - if( index == 0 ) - swapped[i] = 1; - else if( index == 1 ) - swapped[i] = 0; - else if( index <= 5 ) - swapped[i] = 7 - index; - else - swapped[i] = index; - } - - // write the block - WriteAlphaBlock( alpha1, alpha0, swapped, block ); - } - else - { - // write the block - WriteAlphaBlock( alpha0, alpha1, indices, block ); - } -} - -static void WriteAlphaBlock7( int alpha0, int alpha1, u8 const* indices, void* block ) -{ - // check the relative values of the endpoints - if( alpha0 < alpha1 ) - { - // swap the indices - u8 swapped[16]; - for( int i = 0; i < 16; ++i ) - { - u8 index = indices[i]; - if( index == 0 ) - swapped[i] = 1; - else if( index == 1 ) - swapped[i] = 0; - else - swapped[i] = 9 - index; - } - - // write the block - WriteAlphaBlock( alpha1, alpha0, swapped, block ); - } - else - { - // write the block - WriteAlphaBlock( alpha0, alpha1, indices, block ); - } -} - -void CompressAlphaDxt5( u8 const* rgba, int mask, void* block ) -{ - // get the range for 5-alpha and 7-alpha interpolation - int min5 = 255; - int max5 = 0; - int min7 = 255; - int max7 = 0; - for( int i = 0; i < 16; ++i ) - { - // check this pixel is valid - int bit = 1 << i; - if( ( mask & bit ) == 0 ) - continue; - - // incorporate into the min/max - int value = rgba[4*i + 3]; - if( value < min7 ) - min7 = value; - if( value > max7 ) - max7 = value; - if( value != 0 && value < min5 ) - min5 = value; - if( value != 255 && value > max5 ) - max5 = value; - } - - // handle the case that no valid range was found - if( min5 > max5 ) - min5 = max5; - if( min7 > max7 ) - min7 = max7; - - // fix the range to be the minimum in each case - FixRange( min5, max5, 5 ); - FixRange( min7, max7, 7 ); - - // set up the 5-alpha code book - u8 codes5[8]; - codes5[0] = ( u8 )min5; - codes5[1] = ( u8 )max5; - for( int i = 1; i < 5; ++i ) - codes5[1 + i] = ( u8 )( ( ( 5 - i )*min5 + i*max5 )/5 ); - codes5[6] = 0; - codes5[7] = 255; - - // set up the 7-alpha code book - u8 codes7[8]; - codes7[0] = ( u8 )min7; - codes7[1] = ( u8 )max7; - for( int i = 1; i < 7; ++i ) - codes7[1 + i] = ( u8 )( ( ( 7 - i )*min7 + i*max7 )/7 ); - - // fit the data to both code books - u8 indices5[16]; - u8 indices7[16]; - int err5 = FitCodes( rgba, mask, codes5, indices5 ); - int err7 = FitCodes( rgba, mask, codes7, indices7 ); - - // save the block with least error - if( err5 <= err7 ) - WriteAlphaBlock5( min5, max5, indices5, block ); - else - WriteAlphaBlock7( min7, max7, indices7, block ); -} - -void DecompressAlphaDxt5( u8* rgba, void const* block ) -{ - // get the two alpha values - u8 const* bytes = reinterpret_cast< u8 const* >( block ); - int alpha0 = bytes[0]; - int alpha1 = bytes[1]; - - // compare the values to build the codebook - u8 codes[8]; - codes[0] = ( u8 )alpha0; - codes[1] = ( u8 )alpha1; - if( alpha0 <= alpha1 ) - { - // use 5-alpha codebook - for( int i = 1; i < 5; ++i ) - codes[1 + i] = ( u8 )( ( ( 5 - i )*alpha0 + i*alpha1 )/5 ); - codes[6] = 0; - codes[7] = 255; - } - else - { - // use 7-alpha codebook - for( int i = 1; i < 7; ++i ) - codes[1 + i] = ( u8 )( ( ( 7 - i )*alpha0 + i*alpha1 )/7 ); - } - - // decode the indices - u8 indices[16]; - u8 const* src = bytes + 2; - u8* dest = indices; - for( int i = 0; i < 2; ++i ) - { - // grab 3 bytes - int value = 0; - for( int j = 0; j < 3; ++j ) - { - int byte = *src++; - value |= ( byte << 8*j ); - } - - // unpack 8 3-bit values from it - for( int j = 0; j < 8; ++j ) - { - int index = ( value >> 3*j ) & 0x7; - *dest++ = ( u8 )index; - } - } - - // write out the indexed codebook values - for( int i = 0; i < 16; ++i ) - rgba[4*i + 3] = codes[indices[i]]; -} - -} // namespace squish diff --git a/thirdparty/squish/alpha.h b/thirdparty/squish/alpha.h deleted file mode 100644 index a1fffd4049..0000000000 --- a/thirdparty/squish/alpha.h +++ /dev/null @@ -1,41 +0,0 @@ -/* ----------------------------------------------------------------------------- - - Copyright (c) 2006 Simon Brown si@sjbrown.co.uk - - 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 SQUISH_ALPHA_H -#define SQUISH_ALPHA_H - -#include "squish.h" - -namespace squish { - -void CompressAlphaDxt3( u8 const* rgba, int mask, void* block ); -void CompressAlphaDxt5( u8 const* rgba, int mask, void* block ); - -void DecompressAlphaDxt3( u8* rgba, void const* block ); -void DecompressAlphaDxt5( u8* rgba, void const* block ); - -} // namespace squish - -#endif // ndef SQUISH_ALPHA_H diff --git a/thirdparty/squish/clusterfit.cpp b/thirdparty/squish/clusterfit.cpp deleted file mode 100644 index 1610ecb5d8..0000000000 --- a/thirdparty/squish/clusterfit.cpp +++ /dev/null @@ -1,392 +0,0 @@ -/* ----------------------------------------------------------------------------- - - Copyright (c) 2006 Simon Brown si@sjbrown.co.uk - Copyright (c) 2007 Ignacio Castano icastano@nvidia.com - - 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 "clusterfit.h" -#include "colourset.h" -#include "colourblock.h" -#include <cfloat> - -namespace squish { - -ClusterFit::ClusterFit( ColourSet const* colours, int flags, float* metric ) - : ColourFit( colours, flags ) -{ - // set the iteration count - m_iterationCount = ( m_flags & kColourIterativeClusterFit ) ? kMaxIterations : 1; - - // initialise the metric (old perceptual = 0.2126f, 0.7152f, 0.0722f) - if( metric ) - m_metric = Vec4( metric[0], metric[1], metric[2], 1.0f ); - else - m_metric = VEC4_CONST( 1.0f ); - - // initialise the best error - m_besterror = VEC4_CONST( FLT_MAX ); - - // cache some values - int const count = m_colours->GetCount(); - Vec3 const* values = m_colours->GetPoints(); - - // get the covariance matrix - Sym3x3 covariance = ComputeWeightedCovariance( count, values, m_colours->GetWeights() ); - - // compute the principle component - m_principle = ComputePrincipleComponent( covariance ); -} - -bool ClusterFit::ConstructOrdering( Vec3 const& axis, int iteration ) -{ - // cache some values - int const count = m_colours->GetCount(); - Vec3 const* values = m_colours->GetPoints(); - - // build the list of dot products - float dps[16]; - u8* order = ( u8* )m_order + 16*iteration; - for( int i = 0; i < count; ++i ) - { - dps[i] = Dot( values[i], axis ); - order[i] = ( u8 )i; - } - - // stable sort using them - for( int i = 0; i < count; ++i ) - { - for( int j = i; j > 0 && dps[j] < dps[j - 1]; --j ) - { - std::swap( dps[j], dps[j - 1] ); - std::swap( order[j], order[j - 1] ); - } - } - - // check this ordering is unique - for( int it = 0; it < iteration; ++it ) - { - u8 const* prev = ( u8* )m_order + 16*it; - bool same = true; - for( int i = 0; i < count; ++i ) - { - if( order[i] != prev[i] ) - { - same = false; - break; - } - } - if( same ) - return false; - } - - // copy the ordering and weight all the points - Vec3 const* unweighted = m_colours->GetPoints(); - float const* weights = m_colours->GetWeights(); - m_xsum_wsum = VEC4_CONST( 0.0f ); - for( int i = 0; i < count; ++i ) - { - int j = order[i]; - Vec4 p( unweighted[j].X(), unweighted[j].Y(), unweighted[j].Z(), 1.0f ); - Vec4 w( weights[j] ); - Vec4 x = p*w; - m_points_weights[i] = x; - m_xsum_wsum += x; - } - return true; -} - -void ClusterFit::Compress3( void* block ) -{ - // declare variables - int const count = m_colours->GetCount(); - Vec4 const two = VEC4_CONST( 2.0 ); - Vec4 const one = VEC4_CONST( 1.0f ); - Vec4 const half_half2( 0.5f, 0.5f, 0.5f, 0.25f ); - Vec4 const zero = VEC4_CONST( 0.0f ); - Vec4 const half = VEC4_CONST( 0.5f ); - Vec4 const grid( 31.0f, 63.0f, 31.0f, 0.0f ); - Vec4 const gridrcp( 1.0f/31.0f, 1.0f/63.0f, 1.0f/31.0f, 0.0f ); - - // prepare an ordering using the principle axis - ConstructOrdering( m_principle, 0 ); - - // check all possible clusters and iterate on the total order - Vec4 beststart = VEC4_CONST( 0.0f ); - Vec4 bestend = VEC4_CONST( 0.0f ); - Vec4 besterror = m_besterror; - u8 bestindices[16]; - int bestiteration = 0; - int besti = 0, bestj = 0; - - // loop over iterations (we avoid the case that all points in first or last cluster) - for( int iterationIndex = 0;; ) - { - // first cluster [0,i) is at the start - Vec4 part0 = VEC4_CONST( 0.0f ); - for( int i = 0; i < count; ++i ) - { - // second cluster [i,j) is half along - Vec4 part1 = ( i == 0 ) ? m_points_weights[0] : VEC4_CONST( 0.0f ); - int jmin = ( i == 0 ) ? 1 : i; - for( int j = jmin;; ) - { - // last cluster [j,count) is at the end - Vec4 part2 = m_xsum_wsum - part1 - part0; - - // compute least squares terms directly - Vec4 alphax_sum = MultiplyAdd( part1, half_half2, part0 ); - Vec4 alpha2_sum = alphax_sum.SplatW(); - - Vec4 betax_sum = MultiplyAdd( part1, half_half2, part2 ); - Vec4 beta2_sum = betax_sum.SplatW(); - - Vec4 alphabeta_sum = ( part1*half_half2 ).SplatW(); - - // compute the least-squares optimal points - Vec4 factor = Reciprocal( NegativeMultiplySubtract( alphabeta_sum, alphabeta_sum, alpha2_sum*beta2_sum ) ); - Vec4 a = NegativeMultiplySubtract( betax_sum, alphabeta_sum, alphax_sum*beta2_sum )*factor; - Vec4 b = NegativeMultiplySubtract( alphax_sum, alphabeta_sum, betax_sum*alpha2_sum )*factor; - - // clamp to the grid - a = Min( one, Max( zero, a ) ); - b = Min( one, Max( zero, b ) ); - a = Truncate( MultiplyAdd( grid, a, half ) )*gridrcp; - b = Truncate( MultiplyAdd( grid, b, half ) )*gridrcp; - - // compute the error (we skip the constant xxsum) - Vec4 e1 = MultiplyAdd( a*a, alpha2_sum, b*b*beta2_sum ); - Vec4 e2 = NegativeMultiplySubtract( a, alphax_sum, a*b*alphabeta_sum ); - Vec4 e3 = NegativeMultiplySubtract( b, betax_sum, e2 ); - Vec4 e4 = MultiplyAdd( two, e3, e1 ); - - // apply the metric to the error term - Vec4 e5 = e4*m_metric; - Vec4 error = e5.SplatX() + e5.SplatY() + e5.SplatZ(); - - // keep the solution if it wins - if( CompareAnyLessThan( error, besterror ) ) - { - beststart = a; - bestend = b; - besti = i; - bestj = j; - besterror = error; - bestiteration = iterationIndex; - } - - // advance - if( j == count ) - break; - part1 += m_points_weights[j]; - ++j; - } - - // advance - part0 += m_points_weights[i]; - } - - // stop if we didn't improve in this iteration - if( bestiteration != iterationIndex ) - break; - - // advance if possible - ++iterationIndex; - if( iterationIndex == m_iterationCount ) - break; - - // stop if a new iteration is an ordering that has already been tried - Vec3 axis = ( bestend - beststart ).GetVec3(); - if( !ConstructOrdering( axis, iterationIndex ) ) - break; - } - - // save the block if necessary - if( CompareAnyLessThan( besterror, m_besterror ) ) - { - // remap the indices - u8 const* order = ( u8* )m_order + 16*bestiteration; - - u8 unordered[16]; - for( int m = 0; m < besti; ++m ) - unordered[order[m]] = 0; - for( int m = besti; m < bestj; ++m ) - unordered[order[m]] = 2; - for( int m = bestj; m < count; ++m ) - unordered[order[m]] = 1; - - m_colours->RemapIndices( unordered, bestindices ); - - // save the block - WriteColourBlock3( beststart.GetVec3(), bestend.GetVec3(), bestindices, block ); - - // save the error - m_besterror = besterror; - } -} - -void ClusterFit::Compress4( void* block ) -{ - // declare variables - int const count = m_colours->GetCount(); - Vec4 const two = VEC4_CONST( 2.0f ); - Vec4 const one = VEC4_CONST( 1.0f ); - Vec4 const onethird_onethird2( 1.0f/3.0f, 1.0f/3.0f, 1.0f/3.0f, 1.0f/9.0f ); - Vec4 const twothirds_twothirds2( 2.0f/3.0f, 2.0f/3.0f, 2.0f/3.0f, 4.0f/9.0f ); - Vec4 const twonineths = VEC4_CONST( 2.0f/9.0f ); - Vec4 const zero = VEC4_CONST( 0.0f ); - Vec4 const half = VEC4_CONST( 0.5f ); - Vec4 const grid( 31.0f, 63.0f, 31.0f, 0.0f ); - Vec4 const gridrcp( 1.0f/31.0f, 1.0f/63.0f, 1.0f/31.0f, 0.0f ); - - // prepare an ordering using the principle axis - ConstructOrdering( m_principle, 0 ); - - // check all possible clusters and iterate on the total order - Vec4 beststart = VEC4_CONST( 0.0f ); - Vec4 bestend = VEC4_CONST( 0.0f ); - Vec4 besterror = m_besterror; - u8 bestindices[16]; - int bestiteration = 0; - int besti = 0, bestj = 0, bestk = 0; - - // loop over iterations (we avoid the case that all points in first or last cluster) - for( int iterationIndex = 0;; ) - { - // first cluster [0,i) is at the start - Vec4 part0 = VEC4_CONST( 0.0f ); - for( int i = 0; i < count; ++i ) - { - // second cluster [i,j) is one third along - Vec4 part1 = VEC4_CONST( 0.0f ); - for( int j = i;; ) - { - // third cluster [j,k) is two thirds along - Vec4 part2 = ( j == 0 ) ? m_points_weights[0] : VEC4_CONST( 0.0f ); - int kmin = ( j == 0 ) ? 1 : j; - for( int k = kmin;; ) - { - // last cluster [k,count) is at the end - Vec4 part3 = m_xsum_wsum - part2 - part1 - part0; - - // compute least squares terms directly - Vec4 const alphax_sum = MultiplyAdd( part2, onethird_onethird2, MultiplyAdd( part1, twothirds_twothirds2, part0 ) ); - Vec4 const alpha2_sum = alphax_sum.SplatW(); - - Vec4 const betax_sum = MultiplyAdd( part1, onethird_onethird2, MultiplyAdd( part2, twothirds_twothirds2, part3 ) ); - Vec4 const beta2_sum = betax_sum.SplatW(); - - Vec4 const alphabeta_sum = twonineths*( part1 + part2 ).SplatW(); - - // compute the least-squares optimal points - Vec4 factor = Reciprocal( NegativeMultiplySubtract( alphabeta_sum, alphabeta_sum, alpha2_sum*beta2_sum ) ); - Vec4 a = NegativeMultiplySubtract( betax_sum, alphabeta_sum, alphax_sum*beta2_sum )*factor; - Vec4 b = NegativeMultiplySubtract( alphax_sum, alphabeta_sum, betax_sum*alpha2_sum )*factor; - - // clamp to the grid - a = Min( one, Max( zero, a ) ); - b = Min( one, Max( zero, b ) ); - a = Truncate( MultiplyAdd( grid, a, half ) )*gridrcp; - b = Truncate( MultiplyAdd( grid, b, half ) )*gridrcp; - - // compute the error (we skip the constant xxsum) - Vec4 e1 = MultiplyAdd( a*a, alpha2_sum, b*b*beta2_sum ); - Vec4 e2 = NegativeMultiplySubtract( a, alphax_sum, a*b*alphabeta_sum ); - Vec4 e3 = NegativeMultiplySubtract( b, betax_sum, e2 ); - Vec4 e4 = MultiplyAdd( two, e3, e1 ); - - // apply the metric to the error term - Vec4 e5 = e4*m_metric; - Vec4 error = e5.SplatX() + e5.SplatY() + e5.SplatZ(); - - // keep the solution if it wins - if( CompareAnyLessThan( error, besterror ) ) - { - beststart = a; - bestend = b; - besterror = error; - besti = i; - bestj = j; - bestk = k; - bestiteration = iterationIndex; - } - - // advance - if( k == count ) - break; - part2 += m_points_weights[k]; - ++k; - } - - // advance - if( j == count ) - break; - part1 += m_points_weights[j]; - ++j; - } - - // advance - part0 += m_points_weights[i]; - } - - // stop if we didn't improve in this iteration - if( bestiteration != iterationIndex ) - break; - - // advance if possible - ++iterationIndex; - if( iterationIndex == m_iterationCount ) - break; - - // stop if a new iteration is an ordering that has already been tried - Vec3 axis = ( bestend - beststart ).GetVec3(); - if( !ConstructOrdering( axis, iterationIndex ) ) - break; - } - - // save the block if necessary - if( CompareAnyLessThan( besterror, m_besterror ) ) - { - // remap the indices - u8 const* order = ( u8* )m_order + 16*bestiteration; - - u8 unordered[16]; - for( int m = 0; m < besti; ++m ) - unordered[order[m]] = 0; - for( int m = besti; m < bestj; ++m ) - unordered[order[m]] = 2; - for( int m = bestj; m < bestk; ++m ) - unordered[order[m]] = 3; - for( int m = bestk; m < count; ++m ) - unordered[order[m]] = 1; - - m_colours->RemapIndices( unordered, bestindices ); - - // save the block - WriteColourBlock4( beststart.GetVec3(), bestend.GetVec3(), bestindices, block ); - - // save the error - m_besterror = besterror; - } -} - -} // namespace squish diff --git a/thirdparty/squish/clusterfit.h b/thirdparty/squish/clusterfit.h deleted file mode 100644 index 999396b262..0000000000 --- a/thirdparty/squish/clusterfit.h +++ /dev/null @@ -1,61 +0,0 @@ -/* ----------------------------------------------------------------------------- - - Copyright (c) 2006 Simon Brown si@sjbrown.co.uk - Copyright (c) 2007 Ignacio Castano icastano@nvidia.com - - 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 SQUISH_CLUSTERFIT_H -#define SQUISH_CLUSTERFIT_H - -#include "squish.h" -#include "maths.h" -#include "simd.h" -#include "colourfit.h" - -namespace squish { - -class ClusterFit : public ColourFit -{ -public: - ClusterFit( ColourSet const* colours, int flags, float* metric ); - -private: - bool ConstructOrdering( Vec3 const& axis, int iteration ); - - virtual void Compress3( void* block ); - virtual void Compress4( void* block ); - - enum { kMaxIterations = 8 }; - - int m_iterationCount; - Vec3 m_principle; - u8 m_order[16*kMaxIterations]; - Vec4 m_points_weights[16]; - Vec4 m_xsum_wsum; - Vec4 m_metric; - Vec4 m_besterror; -}; - -} // namespace squish - -#endif // ndef SQUISH_CLUSTERFIT_H diff --git a/thirdparty/squish/colourblock.cpp b/thirdparty/squish/colourblock.cpp deleted file mode 100644 index f14c9362bd..0000000000 --- a/thirdparty/squish/colourblock.cpp +++ /dev/null @@ -1,247 +0,0 @@ -/* ----------------------------------------------------------------------------- - - Copyright (c) 2006 Simon Brown si@sjbrown.co.uk - - 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 "colourblock.h" -// -- GODOT start -- -#include "alpha.h" -// -- GODOT end -- - -namespace squish { - -static int FloatToInt( float a, int limit ) -{ - // use ANSI round-to-zero behaviour to get round-to-nearest - int i = ( int )( a + 0.5f ); - - // clamp to the limit - if( i < 0 ) - i = 0; - else if( i > limit ) - i = limit; - - // done - return i; -} - -static int FloatTo565( Vec3::Arg colour ) -{ - // get the components in the correct range - int r = FloatToInt( 31.0f*colour.X(), 31 ); - int g = FloatToInt( 63.0f*colour.Y(), 63 ); - int b = FloatToInt( 31.0f*colour.Z(), 31 ); - - // pack into a single value - return ( r << 11 ) | ( g << 5 ) | b; -} - -static void WriteColourBlock( int a, int b, u8* indices, void* block ) -{ - // get the block as bytes - u8* bytes = ( u8* )block; - - // write the endpoints - bytes[0] = ( u8 )( a & 0xff ); - bytes[1] = ( u8 )( a >> 8 ); - bytes[2] = ( u8 )( b & 0xff ); - bytes[3] = ( u8 )( b >> 8 ); - - // write the indices - for( int i = 0; i < 4; ++i ) - { - u8 const* ind = indices + 4*i; - bytes[4 + i] = ind[0] | ( ind[1] << 2 ) | ( ind[2] << 4 ) | ( ind[3] << 6 ); - } -} - -void WriteColourBlock3( Vec3::Arg start, Vec3::Arg end, u8 const* indices, void* block ) -{ - // get the packed values - int a = FloatTo565( start ); - int b = FloatTo565( end ); - - // remap the indices - u8 remapped[16]; - if( a <= b ) - { - // use the indices directly - for( int i = 0; i < 16; ++i ) - remapped[i] = indices[i]; - } - else - { - // swap a and b - std::swap( a, b ); - for( int i = 0; i < 16; ++i ) - { - if( indices[i] == 0 ) - remapped[i] = 1; - else if( indices[i] == 1 ) - remapped[i] = 0; - else - remapped[i] = indices[i]; - } - } - - // write the block - WriteColourBlock( a, b, remapped, block ); -} - -void WriteColourBlock4( Vec3::Arg start, Vec3::Arg end, u8 const* indices, void* block ) -{ - // get the packed values - int a = FloatTo565( start ); - int b = FloatTo565( end ); - - // remap the indices - u8 remapped[16]; - if( a < b ) - { - // swap a and b - std::swap( a, b ); - for( int i = 0; i < 16; ++i ) - remapped[i] = ( indices[i] ^ 0x1 ) & 0x3; - } - else if( a == b ) - { - // use index 0 - for( int i = 0; i < 16; ++i ) - remapped[i] = 0; - } - else - { - // use the indices directly - for( int i = 0; i < 16; ++i ) - remapped[i] = indices[i]; - } - - // write the block - WriteColourBlock( a, b, remapped, block ); -} - -static int Unpack565( u8 const* packed, u8* colour ) -{ - // build the packed value - int value = ( int )packed[0] | ( ( int )packed[1] << 8 ); - - // get the components in the stored range - u8 red = ( u8 )( ( value >> 11 ) & 0x1f ); - u8 green = ( u8 )( ( value >> 5 ) & 0x3f ); - u8 blue = ( u8 )( value & 0x1f ); - - // scale up to 8 bits - colour[0] = ( red << 3 ) | ( red >> 2 ); - colour[1] = ( green << 2 ) | ( green >> 4 ); - colour[2] = ( blue << 3 ) | ( blue >> 2 ); - colour[3] = 255; - - // return the value - return value; -} - -void DecompressColour( u8* rgba, void const* block, bool isDxt1 ) -{ - // get the block bytes - u8 const* bytes = reinterpret_cast< u8 const* >( block ); - - // unpack the endpoints - u8 codes[16]; - int a = Unpack565( bytes, codes ); - int b = Unpack565( bytes + 2, codes + 4 ); - - // generate the midpoints - for( int i = 0; i < 3; ++i ) - { - int c = codes[i]; - int d = codes[4 + i]; - - if( isDxt1 && a <= b ) - { - codes[8 + i] = ( u8 )( ( c + d )/2 ); - codes[12 + i] = 0; - } - else - { - codes[8 + i] = ( u8 )( ( 2*c + d )/3 ); - codes[12 + i] = ( u8 )( ( c + 2*d )/3 ); - } - } - - // fill in alpha for the intermediate values - codes[8 + 3] = 255; - codes[12 + 3] = ( isDxt1 && a <= b ) ? 0 : 255; - - // unpack the indices - u8 indices[16]; - for( int i = 0; i < 4; ++i ) - { - u8* ind = indices + 4*i; - u8 packed = bytes[4 + i]; - - ind[0] = packed & 0x3; - ind[1] = ( packed >> 2 ) & 0x3; - ind[2] = ( packed >> 4 ) & 0x3; - ind[3] = ( packed >> 6 ) & 0x3; - } - - // store out the colours - for( int i = 0; i < 16; ++i ) - { - u8 offset = 4*indices[i]; - for( int j = 0; j < 4; ++j ) - rgba[4*i + j] = codes[offset + j]; - } -} - -// -- GODOT start -- -void DecompressColourBc4( u8* rgba, void const* block) -{ - DecompressAlphaDxt5(rgba,block); - for ( int i = 0; i < 16; ++i ) { - rgba[i*4] = rgba[i*4 + 3]; - rgba[i*4 + 1] = 0; - rgba[i*4 + 2] = 0; - rgba[i*4 + 3] = 255; - } -} - -void DecompressColourBc5( u8* rgba, void const* block) -{ - void const* rblock = block; - void const* gblock = reinterpret_cast< u8 const* >( block ) + 8; - DecompressAlphaDxt5(rgba,rblock); - for ( int i = 0; i < 16; ++i ) { - rgba[i*4] = rgba[i*4 + 3]; - } - DecompressAlphaDxt5(rgba,gblock); - for ( int i = 0; i < 16; ++i ) { - rgba[i*4+1] = rgba[i*4 + 3]; - rgba[i*4 + 2] = 0; - rgba[i*4 + 3] = 255; - } -} -// -- GODOT end -- - - -} // namespace squish diff --git a/thirdparty/squish/colourblock.h b/thirdparty/squish/colourblock.h deleted file mode 100644 index e1eb9e4917..0000000000 --- a/thirdparty/squish/colourblock.h +++ /dev/null @@ -1,45 +0,0 @@ -/* ----------------------------------------------------------------------------- - - Copyright (c) 2006 Simon Brown si@sjbrown.co.uk - - 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 SQUISH_COLOURBLOCK_H -#define SQUISH_COLOURBLOCK_H - -#include "squish.h" -#include "maths.h" - -namespace squish { - -void WriteColourBlock3( Vec3::Arg start, Vec3::Arg end, u8 const* indices, void* block ); -void WriteColourBlock4( Vec3::Arg start, Vec3::Arg end, u8 const* indices, void* block ); - -void DecompressColour( u8* rgba, void const* block, bool isDxt1 ); -// -- GODOT start -- -void DecompressColourBc4( u8* rgba, void const* block ); -void DecompressColourBc5( u8* rgba, void const* block ); -// -- GODOT end -- - -} // namespace squish - -#endif // ndef SQUISH_COLOURBLOCK_H diff --git a/thirdparty/squish/colourfit.cpp b/thirdparty/squish/colourfit.cpp deleted file mode 100644 index e45b656557..0000000000 --- a/thirdparty/squish/colourfit.cpp +++ /dev/null @@ -1,54 +0,0 @@ -/* ----------------------------------------------------------------------------- - - Copyright (c) 2006 Simon Brown si@sjbrown.co.uk - - 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 "colourfit.h" -#include "colourset.h" - -namespace squish { - -ColourFit::ColourFit( ColourSet const* colours, int flags ) - : m_colours( colours ), - m_flags( flags ) -{ -} - -ColourFit::~ColourFit() -{ -} - -void ColourFit::Compress( void* block ) -{ - bool isDxt1 = ( ( m_flags & kDxt1 ) != 0 ); - if( isDxt1 ) - { - Compress3( block ); - if( !m_colours->IsTransparent() ) - Compress4( block ); - } - else - Compress4( block ); -} - -} // namespace squish diff --git a/thirdparty/squish/colourfit.h b/thirdparty/squish/colourfit.h deleted file mode 100644 index e73dceb2eb..0000000000 --- a/thirdparty/squish/colourfit.h +++ /dev/null @@ -1,56 +0,0 @@ -/* ----------------------------------------------------------------------------- - - Copyright (c) 2006 Simon Brown si@sjbrown.co.uk - - 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 SQUISH_COLOURFIT_H -#define SQUISH_COLOURFIT_H - -#include "squish.h" -#include "maths.h" - -#include <climits> - -namespace squish { - -class ColourSet; - -class ColourFit -{ -public: - ColourFit( ColourSet const* colours, int flags ); - virtual ~ColourFit(); - - void Compress( void* block ); - -protected: - virtual void Compress3( void* block ) = 0; - virtual void Compress4( void* block ) = 0; - - ColourSet const* m_colours; - int m_flags; -}; - -} // namespace squish - -#endif // ndef SQUISH_COLOURFIT_H diff --git a/thirdparty/squish/colourset.cpp b/thirdparty/squish/colourset.cpp deleted file mode 100644 index e900556471..0000000000 --- a/thirdparty/squish/colourset.cpp +++ /dev/null @@ -1,121 +0,0 @@ -/* ----------------------------------------------------------------------------- - - Copyright (c) 2006 Simon Brown si@sjbrown.co.uk - - 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 "colourset.h" - -namespace squish { - -ColourSet::ColourSet( u8 const* rgba, int mask, int flags ) - : m_count( 0 ), - m_transparent( false ) -{ - // check the compression mode for dxt1 - bool isDxt1 = ( ( flags & kDxt1 ) != 0 ); - bool weightByAlpha = ( ( flags & kWeightColourByAlpha ) != 0 ); - - // create the minimal set - for( int i = 0; i < 16; ++i ) - { - // check this pixel is enabled - int bit = 1 << i; - if( ( mask & bit ) == 0 ) - { - m_remap[i] = -1; - continue; - } - - // check for transparent pixels when using dxt1 - if( isDxt1 && rgba[4*i + 3] < 128 ) - { - m_remap[i] = -1; - m_transparent = true; - continue; - } - - // loop over previous points for a match - for( int j = 0;; ++j ) - { - // allocate a new point - if( j == i ) - { - // normalise coordinates to [0,1] - float x = ( float )rgba[4*i] / 255.0f; - float y = ( float )rgba[4*i + 1] / 255.0f; - float z = ( float )rgba[4*i + 2] / 255.0f; - - // ensure there is always non-zero weight even for zero alpha - float w = ( float )( rgba[4*i + 3] + 1 ) / 256.0f; - - // add the point - m_points[m_count] = Vec3( x, y, z ); - m_weights[m_count] = ( weightByAlpha ? w : 1.0f ); - m_remap[i] = m_count; - - // advance - ++m_count; - break; - } - - // check for a match - int oldbit = 1 << j; - bool match = ( ( mask & oldbit ) != 0 ) - && ( rgba[4*i] == rgba[4*j] ) - && ( rgba[4*i + 1] == rgba[4*j + 1] ) - && ( rgba[4*i + 2] == rgba[4*j + 2] ) - && ( rgba[4*j + 3] >= 128 || !isDxt1 ); - if( match ) - { - // get the index of the match - int index = m_remap[j]; - - // ensure there is always non-zero weight even for zero alpha - float w = ( float )( rgba[4*i + 3] + 1 ) / 256.0f; - - // map to this point and increase the weight - m_weights[index] += ( weightByAlpha ? w : 1.0f ); - m_remap[i] = index; - break; - } - } - } - - // square root the weights - for( int i = 0; i < m_count; ++i ) - m_weights[i] = std::sqrt( m_weights[i] ); -} - -void ColourSet::RemapIndices( u8 const* source, u8* target ) const -{ - for( int i = 0; i < 16; ++i ) - { - int j = m_remap[i]; - if( j == -1 ) - target[i] = 3; - else - target[i] = source[j]; - } -} - -} // namespace squish diff --git a/thirdparty/squish/colourset.h b/thirdparty/squish/colourset.h deleted file mode 100644 index e13bb6fc35..0000000000 --- a/thirdparty/squish/colourset.h +++ /dev/null @@ -1,58 +0,0 @@ -/* ----------------------------------------------------------------------------- - - Copyright (c) 2006 Simon Brown si@sjbrown.co.uk - - 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 SQUISH_COLOURSET_H -#define SQUISH_COLOURSET_H - -#include "squish.h" -#include "maths.h" - -namespace squish { - -/*! @brief Represents a set of block colours -*/ -class ColourSet -{ -public: - ColourSet( u8 const* rgba, int mask, int flags ); - - int GetCount() const { return m_count; } - Vec3 const* GetPoints() const { return m_points; } - float const* GetWeights() const { return m_weights; } - bool IsTransparent() const { return m_transparent; } - - void RemapIndices( u8 const* source, u8* target ) const; - -private: - int m_count; - Vec3 m_points[16]; - float m_weights[16]; - int m_remap[16]; - bool m_transparent; -}; - -} // namespace sqish - -#endif // ndef SQUISH_COLOURSET_H diff --git a/thirdparty/squish/config.h b/thirdparty/squish/config.h deleted file mode 100644 index 05f8d72598..0000000000 --- a/thirdparty/squish/config.h +++ /dev/null @@ -1,69 +0,0 @@ -/* ----------------------------------------------------------------------------- - - Copyright (c) 2006 Simon Brown si@sjbrown.co.uk - - 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 SQUISH_CONFIG_H -#define SQUISH_CONFIG_H - -// Set to 1 when building squish to use Altivec instructions. -#ifndef SQUISH_USE_ALTIVEC -#define SQUISH_USE_ALTIVEC 0 -#endif - -// Set to 1 or 2 when building squish to use SSE or SSE2 instructions. -// -- GODOT start -- -#ifdef _MSC_VER - #if defined(_M_IX86_FP) - #if _M_IX86_FP >= 2 - #define SQUISH_USE_SSE 2 - #elif _M_IX86_FP >= 1 - #define SQUISH_USE_SSE 1 - #endif - #elif defined(_M_X64) - #define SQUISH_USE_SSE 2 - #endif -#else - #if defined(__SSE2__) - #define SQUISH_USE_SSE 2 - #elif defined(__SSE__) - #define SQUISH_USE_SSE 1 - #endif -#endif -// -- GODOT end -- - -#ifndef SQUISH_USE_SSE -#define SQUISH_USE_SSE 0 -#endif - -// Internally set SQUISH_USE_SIMD when either Altivec or SSE is available. -#if SQUISH_USE_ALTIVEC && SQUISH_USE_SSE -#error "Cannot enable both Altivec and SSE!" -#endif -#if SQUISH_USE_ALTIVEC || SQUISH_USE_SSE -#define SQUISH_USE_SIMD 1 -#else -#define SQUISH_USE_SIMD 0 -#endif - -#endif // ndef SQUISH_CONFIG_H diff --git a/thirdparty/squish/maths.cpp b/thirdparty/squish/maths.cpp deleted file mode 100644 index 4fa0bcfb35..0000000000 --- a/thirdparty/squish/maths.cpp +++ /dev/null @@ -1,259 +0,0 @@ -/* ----------------------------------------------------------------------------- - - Copyright (c) 2006 Simon Brown si@sjbrown.co.uk - - 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. - - -------------------------------------------------------------------------- */ - -/*! @file - - The symmetric eigensystem solver algorithm is from - http://www.geometrictools.com/Documentation/EigenSymmetric3x3.pdf -*/ - -#include "maths.h" -#include "simd.h" -#include <cfloat> - -namespace squish { - -Sym3x3 ComputeWeightedCovariance( int n, Vec3 const* points, float const* weights ) -{ - // compute the centroid - float total = 0.0f; - Vec3 centroid( 0.0f ); - for( int i = 0; i < n; ++i ) - { - total += weights[i]; - centroid += weights[i]*points[i]; - } - if( total > FLT_EPSILON ) - centroid /= total; - - // accumulate the covariance matrix - Sym3x3 covariance( 0.0f ); - for( int i = 0; i < n; ++i ) - { - Vec3 a = points[i] - centroid; - Vec3 b = weights[i]*a; - - covariance[0] += a.X()*b.X(); - covariance[1] += a.X()*b.Y(); - covariance[2] += a.X()*b.Z(); - covariance[3] += a.Y()*b.Y(); - covariance[4] += a.Y()*b.Z(); - covariance[5] += a.Z()*b.Z(); - } - - // return it - return covariance; -} - -#if 0 - -static Vec3 GetMultiplicity1Evector( Sym3x3 const& matrix, float evalue ) -{ - // compute M - Sym3x3 m; - m[0] = matrix[0] - evalue; - m[1] = matrix[1]; - m[2] = matrix[2]; - m[3] = matrix[3] - evalue; - m[4] = matrix[4]; - m[5] = matrix[5] - evalue; - - // compute U - Sym3x3 u; - u[0] = m[3]*m[5] - m[4]*m[4]; - u[1] = m[2]*m[4] - m[1]*m[5]; - u[2] = m[1]*m[4] - m[2]*m[3]; - u[3] = m[0]*m[5] - m[2]*m[2]; - u[4] = m[1]*m[2] - m[4]*m[0]; - u[5] = m[0]*m[3] - m[1]*m[1]; - - // find the largest component - float mc = std::fabs( u[0] ); - int mi = 0; - for( int i = 1; i < 6; ++i ) - { - float c = std::fabs( u[i] ); - if( c > mc ) - { - mc = c; - mi = i; - } - } - - // pick the column with this component - switch( mi ) - { - case 0: - return Vec3( u[0], u[1], u[2] ); - - case 1: - case 3: - return Vec3( u[1], u[3], u[4] ); - - default: - return Vec3( u[2], u[4], u[5] ); - } -} - -static Vec3 GetMultiplicity2Evector( Sym3x3 const& matrix, float evalue ) -{ - // compute M - Sym3x3 m; - m[0] = matrix[0] - evalue; - m[1] = matrix[1]; - m[2] = matrix[2]; - m[3] = matrix[3] - evalue; - m[4] = matrix[4]; - m[5] = matrix[5] - evalue; - - // find the largest component - float mc = std::fabs( m[0] ); - int mi = 0; - for( int i = 1; i < 6; ++i ) - { - float c = std::fabs( m[i] ); - if( c > mc ) - { - mc = c; - mi = i; - } - } - - // pick the first eigenvector based on this index - switch( mi ) - { - case 0: - case 1: - return Vec3( -m[1], m[0], 0.0f ); - - case 2: - return Vec3( m[2], 0.0f, -m[0] ); - - case 3: - case 4: - return Vec3( 0.0f, -m[4], m[3] ); - - default: - return Vec3( 0.0f, -m[5], m[4] ); - } -} - -Vec3 ComputePrincipleComponent( Sym3x3 const& matrix ) -{ - // compute the cubic coefficients - float c0 = matrix[0]*matrix[3]*matrix[5] - + 2.0f*matrix[1]*matrix[2]*matrix[4] - - matrix[0]*matrix[4]*matrix[4] - - matrix[3]*matrix[2]*matrix[2] - - matrix[5]*matrix[1]*matrix[1]; - float c1 = matrix[0]*matrix[3] + matrix[0]*matrix[5] + matrix[3]*matrix[5] - - matrix[1]*matrix[1] - matrix[2]*matrix[2] - matrix[4]*matrix[4]; - float c2 = matrix[0] + matrix[3] + matrix[5]; - - // compute the quadratic coefficients - float a = c1 - ( 1.0f/3.0f )*c2*c2; - float b = ( -2.0f/27.0f )*c2*c2*c2 + ( 1.0f/3.0f )*c1*c2 - c0; - - // compute the root count check - float Q = 0.25f*b*b + ( 1.0f/27.0f )*a*a*a; - - // test the multiplicity - if( FLT_EPSILON < Q ) - { - // only one root, which implies we have a multiple of the identity - return Vec3( 1.0f ); - } - else if( Q < -FLT_EPSILON ) - { - // three distinct roots - float theta = std::atan2( std::sqrt( -Q ), -0.5f*b ); - float rho = std::sqrt( 0.25f*b*b - Q ); - - float rt = std::pow( rho, 1.0f/3.0f ); - float ct = std::cos( theta/3.0f ); - float st = std::sin( theta/3.0f ); - - float l1 = ( 1.0f/3.0f )*c2 + 2.0f*rt*ct; - float l2 = ( 1.0f/3.0f )*c2 - rt*( ct + ( float )sqrt( 3.0f )*st ); - float l3 = ( 1.0f/3.0f )*c2 - rt*( ct - ( float )sqrt( 3.0f )*st ); - - // pick the larger - if( std::fabs( l2 ) > std::fabs( l1 ) ) - l1 = l2; - if( std::fabs( l3 ) > std::fabs( l1 ) ) - l1 = l3; - - // get the eigenvector - return GetMultiplicity1Evector( matrix, l1 ); - } - else // if( -FLT_EPSILON <= Q && Q <= FLT_EPSILON ) - { - // two roots - float rt; - if( b < 0.0f ) - rt = -std::pow( -0.5f*b, 1.0f/3.0f ); - else - rt = std::pow( 0.5f*b, 1.0f/3.0f ); - - float l1 = ( 1.0f/3.0f )*c2 + rt; // repeated - float l2 = ( 1.0f/3.0f )*c2 - 2.0f*rt; - - // get the eigenvector - if( std::fabs( l1 ) > std::fabs( l2 ) ) - return GetMultiplicity2Evector( matrix, l1 ); - else - return GetMultiplicity1Evector( matrix, l2 ); - } -} - -#else - -#define POWER_ITERATION_COUNT 8 - -Vec3 ComputePrincipleComponent( Sym3x3 const& matrix ) -{ - Vec4 const row0( matrix[0], matrix[1], matrix[2], 0.0f ); - Vec4 const row1( matrix[1], matrix[3], matrix[4], 0.0f ); - Vec4 const row2( matrix[2], matrix[4], matrix[5], 0.0f ); - Vec4 v = VEC4_CONST( 1.0f ); - for( int i = 0; i < POWER_ITERATION_COUNT; ++i ) - { - // matrix multiply - Vec4 w = row0*v.SplatX(); - w = MultiplyAdd(row1, v.SplatY(), w); - w = MultiplyAdd(row2, v.SplatZ(), w); - - // get max component from xyz in all channels - Vec4 a = Max(w.SplatX(), Max(w.SplatY(), w.SplatZ())); - - // divide through and advance - v = w*Reciprocal(a); - } - return v.GetVec3(); -} - -#endif - -} // namespace squish diff --git a/thirdparty/squish/maths.h b/thirdparty/squish/maths.h deleted file mode 100644 index 59c32196b1..0000000000 --- a/thirdparty/squish/maths.h +++ /dev/null @@ -1,233 +0,0 @@ -/* ----------------------------------------------------------------------------- - - Copyright (c) 2006 Simon Brown si@sjbrown.co.uk - - 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 SQUISH_MATHS_H -#define SQUISH_MATHS_H - -#include <cmath> -#include <algorithm> -#include "config.h" - -namespace squish { - -class Vec3 -{ -public: - typedef Vec3 const& Arg; - - Vec3() - { - } - - explicit Vec3( float s ) - { - m_x = s; - m_y = s; - m_z = s; - } - - Vec3( float x, float y, float z ) - { - m_x = x; - m_y = y; - m_z = z; - } - - float X() const { return m_x; } - float Y() const { return m_y; } - float Z() const { return m_z; } - - Vec3 operator-() const - { - return Vec3( -m_x, -m_y, -m_z ); - } - - Vec3& operator+=( Arg v ) - { - m_x += v.m_x; - m_y += v.m_y; - m_z += v.m_z; - return *this; - } - - Vec3& operator-=( Arg v ) - { - m_x -= v.m_x; - m_y -= v.m_y; - m_z -= v.m_z; - return *this; - } - - Vec3& operator*=( Arg v ) - { - m_x *= v.m_x; - m_y *= v.m_y; - m_z *= v.m_z; - return *this; - } - - Vec3& operator*=( float s ) - { - m_x *= s; - m_y *= s; - m_z *= s; - return *this; - } - - Vec3& operator/=( Arg v ) - { - m_x /= v.m_x; - m_y /= v.m_y; - m_z /= v.m_z; - return *this; - } - - Vec3& operator/=( float s ) - { - float t = 1.0f/s; - m_x *= t; - m_y *= t; - m_z *= t; - return *this; - } - - friend Vec3 operator+( Arg left, Arg right ) - { - Vec3 copy( left ); - return copy += right; - } - - friend Vec3 operator-( Arg left, Arg right ) - { - Vec3 copy( left ); - return copy -= right; - } - - friend Vec3 operator*( Arg left, Arg right ) - { - Vec3 copy( left ); - return copy *= right; - } - - friend Vec3 operator*( Arg left, float right ) - { - Vec3 copy( left ); - return copy *= right; - } - - friend Vec3 operator*( float left, Arg right ) - { - Vec3 copy( right ); - return copy *= left; - } - - friend Vec3 operator/( Arg left, Arg right ) - { - Vec3 copy( left ); - return copy /= right; - } - - friend Vec3 operator/( Arg left, float right ) - { - Vec3 copy( left ); - return copy /= right; - } - - friend float Dot( Arg left, Arg right ) - { - return left.m_x*right.m_x + left.m_y*right.m_y + left.m_z*right.m_z; - } - - friend Vec3 Min( Arg left, Arg right ) - { - return Vec3( - std::min( left.m_x, right.m_x ), - std::min( left.m_y, right.m_y ), - std::min( left.m_z, right.m_z ) - ); - } - - friend Vec3 Max( Arg left, Arg right ) - { - return Vec3( - std::max( left.m_x, right.m_x ), - std::max( left.m_y, right.m_y ), - std::max( left.m_z, right.m_z ) - ); - } - - friend Vec3 Truncate( Arg v ) - { - return Vec3( - v.m_x > 0.0f ? std::floor( v.m_x ) : std::ceil( v.m_x ), - v.m_y > 0.0f ? std::floor( v.m_y ) : std::ceil( v.m_y ), - v.m_z > 0.0f ? std::floor( v.m_z ) : std::ceil( v.m_z ) - ); - } - -private: - float m_x; - float m_y; - float m_z; -}; - -inline float LengthSquared( Vec3::Arg v ) -{ - return Dot( v, v ); -} - -class Sym3x3 -{ -public: - Sym3x3() - { - } - - Sym3x3( float s ) - { - for( int i = 0; i < 6; ++i ) - m_x[i] = s; - } - - float operator[]( int index ) const - { - return m_x[index]; - } - - float& operator[]( int index ) - { - return m_x[index]; - } - -private: - float m_x[6]; -}; - -Sym3x3 ComputeWeightedCovariance( int n, Vec3 const* points, float const* weights ); -Vec3 ComputePrincipleComponent( Sym3x3 const& matrix ); - -} // namespace squish - -#endif // ndef SQUISH_MATHS_H diff --git a/thirdparty/squish/patches/config_sse.patch b/thirdparty/squish/patches/config_sse.patch deleted file mode 100644 index 047701ee32..0000000000 --- a/thirdparty/squish/patches/config_sse.patch +++ /dev/null @@ -1,31 +0,0 @@ -diff --git a/thirdparty/squish/config.h b/thirdparty/squish/config.h -index 92edefe966..05f8d72598 100644 ---- a/thirdparty/squish/config.h -+++ b/thirdparty/squish/config.h -@@ -32,6 +32,26 @@ - #endif - - // Set to 1 or 2 when building squish to use SSE or SSE2 instructions. -+// -- GODOT start -- -+#ifdef _MSC_VER -+ #if defined(_M_IX86_FP) -+ #if _M_IX86_FP >= 2 -+ #define SQUISH_USE_SSE 2 -+ #elif _M_IX86_FP >= 1 -+ #define SQUISH_USE_SSE 1 -+ #endif -+ #elif defined(_M_X64) -+ #define SQUISH_USE_SSE 2 -+ #endif -+#else -+ #if defined(__SSE2__) -+ #define SQUISH_USE_SSE 2 -+ #elif defined(__SSE__) -+ #define SQUISH_USE_SSE 1 -+ #endif -+#endif -+// -- GODOT end -- -+ - #ifndef SQUISH_USE_SSE - #define SQUISH_USE_SSE 0 - #endif diff --git a/thirdparty/squish/patches/decompress_bc4_bc5.patch b/thirdparty/squish/patches/decompress_bc4_bc5.patch deleted file mode 100644 index 949375560c..0000000000 --- a/thirdparty/squish/patches/decompress_bc4_bc5.patch +++ /dev/null @@ -1,85 +0,0 @@ -diff --git a/thirdparty/squish/colourblock.cpp b/thirdparty/squish/colourblock.cpp -index af8b980365..f14c9362bd 100644 ---- a/thirdparty/squish/colourblock.cpp -+++ b/thirdparty/squish/colourblock.cpp -@@ -24,6 +24,9 @@ - -------------------------------------------------------------------------- */ - - #include "colourblock.h" -+// -- GODOT start -- -+#include "alpha.h" -+// -- GODOT end -- - - namespace squish { - -@@ -211,4 +214,34 @@ void DecompressColour( u8* rgba, void const* block, bool isDxt1 ) - } - } - -+// -- GODOT start -- -+void DecompressColourBc4( u8* rgba, void const* block) -+{ -+ DecompressAlphaDxt5(rgba,block); -+ for ( int i = 0; i < 16; ++i ) { -+ rgba[i*4] = rgba[i*4 + 3]; -+ rgba[i*4 + 1] = 0; -+ rgba[i*4 + 2] = 0; -+ rgba[i*4 + 3] = 255; -+ } -+} -+ -+void DecompressColourBc5( u8* rgba, void const* block) -+{ -+ void const* rblock = block; -+ void const* gblock = reinterpret_cast< u8 const* >( block ) + 8; -+ DecompressAlphaDxt5(rgba,rblock); -+ for ( int i = 0; i < 16; ++i ) { -+ rgba[i*4] = rgba[i*4 + 3]; -+ } -+ DecompressAlphaDxt5(rgba,gblock); -+ for ( int i = 0; i < 16; ++i ) { -+ rgba[i*4+1] = rgba[i*4 + 3]; -+ rgba[i*4 + 2] = 0; -+ rgba[i*4 + 3] = 255; -+ } -+} -+// -- GODOT end -- -+ -+ - } // namespace squish -diff --git a/thirdparty/squish/colourblock.h b/thirdparty/squish/colourblock.h -index fee2cd7c5d..e1eb9e4917 100644 ---- a/thirdparty/squish/colourblock.h -+++ b/thirdparty/squish/colourblock.h -@@ -35,6 +35,10 @@ void WriteColourBlock3( Vec3::Arg start, Vec3::Arg end, u8 const* indices, void* - void WriteColourBlock4( Vec3::Arg start, Vec3::Arg end, u8 const* indices, void* block ); - - void DecompressColour( u8* rgba, void const* block, bool isDxt1 ); -+// -- GODOT start -- -+void DecompressColourBc4( u8* rgba, void const* block ); -+void DecompressColourBc5( u8* rgba, void const* block ); -+// -- GODOT end -- - - } // namespace squish - -diff --git a/thirdparty/squish/squish.cpp b/thirdparty/squish/squish.cpp -index 1d22a64ad6..086ba11cd0 100644 ---- a/thirdparty/squish/squish.cpp -+++ b/thirdparty/squish/squish.cpp -@@ -135,7 +135,15 @@ void Decompress( u8* rgba, void const* block, int flags ) - colourBlock = reinterpret_cast< u8 const* >( block ) + 8; - - // decompress colour -- DecompressColour( rgba, colourBlock, ( flags & kDxt1 ) != 0 ); -+ // -- GODOT start -- -+ //DecompressColour( rgba, colourBlock, ( flags & kDxt1 ) != 0 ); -+ if(( flags & ( kBc4 ) ) != 0) -+ DecompressColourBc4( rgba, colourBlock); -+ else if(( flags & ( kBc5 ) ) != 0) -+ DecompressColourBc5( rgba, colourBlock); -+ else -+ DecompressColour( rgba, colourBlock, ( flags & kDxt1 ) != 0 ); -+ // -- GODOT end -- - - // decompress alpha separately if necessary - if( ( flags & kDxt3 ) != 0 ) diff --git a/thirdparty/squish/rangefit.cpp b/thirdparty/squish/rangefit.cpp deleted file mode 100644 index adc07ed7d2..0000000000 --- a/thirdparty/squish/rangefit.cpp +++ /dev/null @@ -1,201 +0,0 @@ -/* ----------------------------------------------------------------------------- - - Copyright (c) 2006 Simon Brown si@sjbrown.co.uk - - 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 "rangefit.h" -#include "colourset.h" -#include "colourblock.h" -#include <cfloat> - -namespace squish { - -RangeFit::RangeFit( ColourSet const* colours, int flags, float* metric ) - : ColourFit( colours, flags ) -{ - // initialise the metric (old perceptual = 0.2126f, 0.7152f, 0.0722f) - if( metric ) - m_metric = Vec3( metric[0], metric[1], metric[2] ); - else - m_metric = Vec3( 1.0f ); - - // initialise the best error - m_besterror = FLT_MAX; - - // cache some values - int const count = m_colours->GetCount(); - Vec3 const* values = m_colours->GetPoints(); - float const* weights = m_colours->GetWeights(); - - // get the covariance matrix - Sym3x3 covariance = ComputeWeightedCovariance( count, values, weights ); - - // compute the principle component - Vec3 principle = ComputePrincipleComponent( covariance ); - - // get the min and max range as the codebook endpoints - Vec3 start( 0.0f ); - Vec3 end( 0.0f ); - if( count > 0 ) - { - float min, max; - - // compute the range - start = end = values[0]; - min = max = Dot( values[0], principle ); - for( int i = 1; i < count; ++i ) - { - float val = Dot( values[i], principle ); - if( val < min ) - { - start = values[i]; - min = val; - } - else if( val > max ) - { - end = values[i]; - max = val; - } - } - } - - // clamp the output to [0, 1] - Vec3 const one( 1.0f ); - Vec3 const zero( 0.0f ); - start = Min( one, Max( zero, start ) ); - end = Min( one, Max( zero, end ) ); - - // clamp to the grid and save - Vec3 const grid( 31.0f, 63.0f, 31.0f ); - Vec3 const gridrcp( 1.0f/31.0f, 1.0f/63.0f, 1.0f/31.0f ); - Vec3 const half( 0.5f ); - m_start = Truncate( grid*start + half )*gridrcp; - m_end = Truncate( grid*end + half )*gridrcp; -} - -void RangeFit::Compress3( void* block ) -{ - // cache some values - int const count = m_colours->GetCount(); - Vec3 const* values = m_colours->GetPoints(); - - // create a codebook - Vec3 codes[3]; - codes[0] = m_start; - codes[1] = m_end; - codes[2] = 0.5f*m_start + 0.5f*m_end; - - // match each point to the closest code - u8 closest[16]; - float error = 0.0f; - for( int i = 0; i < count; ++i ) - { - // find the closest code - float dist = FLT_MAX; - int idx = 0; - for( int j = 0; j < 3; ++j ) - { - float d = LengthSquared( m_metric*( values[i] - codes[j] ) ); - if( d < dist ) - { - dist = d; - idx = j; - } - } - - // save the index - closest[i] = ( u8 )idx; - - // accumulate the error - error += dist; - } - - // save this scheme if it wins - if( error < m_besterror ) - { - // remap the indices - u8 indices[16]; - m_colours->RemapIndices( closest, indices ); - - // save the block - WriteColourBlock3( m_start, m_end, indices, block ); - - // save the error - m_besterror = error; - } -} - -void RangeFit::Compress4( void* block ) -{ - // cache some values - int const count = m_colours->GetCount(); - Vec3 const* values = m_colours->GetPoints(); - - // create a codebook - Vec3 codes[4]; - codes[0] = m_start; - codes[1] = m_end; - codes[2] = ( 2.0f/3.0f )*m_start + ( 1.0f/3.0f )*m_end; - codes[3] = ( 1.0f/3.0f )*m_start + ( 2.0f/3.0f )*m_end; - - // match each point to the closest code - u8 closest[16]; - float error = 0.0f; - for( int i = 0; i < count; ++i ) - { - // find the closest code - float dist = FLT_MAX; - int idx = 0; - for( int j = 0; j < 4; ++j ) - { - float d = LengthSquared( m_metric*( values[i] - codes[j] ) ); - if( d < dist ) - { - dist = d; - idx = j; - } - } - - // save the index - closest[i] = ( u8 )idx; - - // accumulate the error - error += dist; - } - - // save this scheme if it wins - if( error < m_besterror ) - { - // remap the indices - u8 indices[16]; - m_colours->RemapIndices( closest, indices ); - - // save the block - WriteColourBlock4( m_start, m_end, indices, block ); - - // save the error - m_besterror = error; - } -} - -} // namespace squish diff --git a/thirdparty/squish/rangefit.h b/thirdparty/squish/rangefit.h deleted file mode 100644 index bdb21a9007..0000000000 --- a/thirdparty/squish/rangefit.h +++ /dev/null @@ -1,54 +0,0 @@ -/* ----------------------------------------------------------------------------- - - Copyright (c) 2006 Simon Brown si@sjbrown.co.uk - - 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 SQUISH_RANGEFIT_H -#define SQUISH_RANGEFIT_H - -#include "squish.h" -#include "colourfit.h" -#include "maths.h" - -namespace squish { - -class ColourSet; - -class RangeFit : public ColourFit -{ -public: - RangeFit( ColourSet const* colours, int flags, float* metric ); - -private: - virtual void Compress3( void* block ); - virtual void Compress4( void* block ); - - Vec3 m_metric; - Vec3 m_start; - Vec3 m_end; - float m_besterror; -}; - -} // squish - -#endif // ndef SQUISH_RANGEFIT_H diff --git a/thirdparty/squish/simd.h b/thirdparty/squish/simd.h deleted file mode 100644 index 1e02fa160e..0000000000 --- a/thirdparty/squish/simd.h +++ /dev/null @@ -1,40 +0,0 @@ -/* ----------------------------------------------------------------------------- - - Copyright (c) 2006 Simon Brown si@sjbrown.co.uk - - 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 SQUISH_SIMD_H -#define SQUISH_SIMD_H - -#include "maths.h" - -#if SQUISH_USE_ALTIVEC -#include "simd_ve.h" -#elif SQUISH_USE_SSE -#include "simd_sse.h" -#else -#include "simd_float.h" -#endif - - -#endif // ndef SQUISH_SIMD_H diff --git a/thirdparty/squish/simd_float.h b/thirdparty/squish/simd_float.h deleted file mode 100644 index 030ea70950..0000000000 --- a/thirdparty/squish/simd_float.h +++ /dev/null @@ -1,183 +0,0 @@ -/* ----------------------------------------------------------------------------- - - Copyright (c) 2006 Simon Brown si@sjbrown.co.uk - - 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 SQUISH_SIMD_FLOAT_H -#define SQUISH_SIMD_FLOAT_H - -#include <algorithm> - -namespace squish { - -#define VEC4_CONST( X ) Vec4( X ) - -class Vec4 -{ -public: - typedef Vec4 const& Arg; - - Vec4() {} - - explicit Vec4( float s ) - : m_x( s ), - m_y( s ), - m_z( s ), - m_w( s ) - { - } - - Vec4( float x, float y, float z, float w ) - : m_x( x ), - m_y( y ), - m_z( z ), - m_w( w ) - { - } - - Vec3 GetVec3() const - { - return Vec3( m_x, m_y, m_z ); - } - - Vec4 SplatX() const { return Vec4( m_x ); } - Vec4 SplatY() const { return Vec4( m_y ); } - Vec4 SplatZ() const { return Vec4( m_z ); } - Vec4 SplatW() const { return Vec4( m_w ); } - - Vec4& operator+=( Arg v ) - { - m_x += v.m_x; - m_y += v.m_y; - m_z += v.m_z; - m_w += v.m_w; - return *this; - } - - Vec4& operator-=( Arg v ) - { - m_x -= v.m_x; - m_y -= v.m_y; - m_z -= v.m_z; - m_w -= v.m_w; - return *this; - } - - Vec4& operator*=( Arg v ) - { - m_x *= v.m_x; - m_y *= v.m_y; - m_z *= v.m_z; - m_w *= v.m_w; - return *this; - } - - friend Vec4 operator+( Vec4::Arg left, Vec4::Arg right ) - { - Vec4 copy( left ); - return copy += right; - } - - friend Vec4 operator-( Vec4::Arg left, Vec4::Arg right ) - { - Vec4 copy( left ); - return copy -= right; - } - - friend Vec4 operator*( Vec4::Arg left, Vec4::Arg right ) - { - Vec4 copy( left ); - return copy *= right; - } - - //! Returns a*b + c - friend Vec4 MultiplyAdd( Vec4::Arg a, Vec4::Arg b, Vec4::Arg c ) - { - return a*b + c; - } - - //! Returns -( a*b - c ) - friend Vec4 NegativeMultiplySubtract( Vec4::Arg a, Vec4::Arg b, Vec4::Arg c ) - { - return c - a*b; - } - - friend Vec4 Reciprocal( Vec4::Arg v ) - { - return Vec4( - 1.0f/v.m_x, - 1.0f/v.m_y, - 1.0f/v.m_z, - 1.0f/v.m_w - ); - } - - friend Vec4 Min( Vec4::Arg left, Vec4::Arg right ) - { - return Vec4( - std::min( left.m_x, right.m_x ), - std::min( left.m_y, right.m_y ), - std::min( left.m_z, right.m_z ), - std::min( left.m_w, right.m_w ) - ); - } - - friend Vec4 Max( Vec4::Arg left, Vec4::Arg right ) - { - return Vec4( - std::max( left.m_x, right.m_x ), - std::max( left.m_y, right.m_y ), - std::max( left.m_z, right.m_z ), - std::max( left.m_w, right.m_w ) - ); - } - - friend Vec4 Truncate( Vec4::Arg v ) - { - return Vec4( - v.m_x > 0.0f ? std::floor( v.m_x ) : std::ceil( v.m_x ), - v.m_y > 0.0f ? std::floor( v.m_y ) : std::ceil( v.m_y ), - v.m_z > 0.0f ? std::floor( v.m_z ) : std::ceil( v.m_z ), - v.m_w > 0.0f ? std::floor( v.m_w ) : std::ceil( v.m_w ) - ); - } - - friend bool CompareAnyLessThan( Vec4::Arg left, Vec4::Arg right ) - { - return left.m_x < right.m_x - || left.m_y < right.m_y - || left.m_z < right.m_z - || left.m_w < right.m_w; - } - -private: - float m_x; - float m_y; - float m_z; - float m_w; -}; - -} // namespace squish - -#endif // ndef SQUISH_SIMD_FLOAT_H - diff --git a/thirdparty/squish/simd_sse.h b/thirdparty/squish/simd_sse.h deleted file mode 100644 index 2e8be4ca7b..0000000000 --- a/thirdparty/squish/simd_sse.h +++ /dev/null @@ -1,180 +0,0 @@ -/* ----------------------------------------------------------------------------- - - Copyright (c) 2006 Simon Brown si@sjbrown.co.uk - - 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 SQUISH_SIMD_SSE_H -#define SQUISH_SIMD_SSE_H - -#include <xmmintrin.h> -#if ( SQUISH_USE_SSE > 1 ) -#include <emmintrin.h> -#endif - -#define SQUISH_SSE_SPLAT( a ) \ - ( ( a ) | ( ( a ) << 2 ) | ( ( a ) << 4 ) | ( ( a ) << 6 ) ) - -#define SQUISH_SSE_SHUF( x, y, z, w ) \ - ( ( x ) | ( ( y ) << 2 ) | ( ( z ) << 4 ) | ( ( w ) << 6 ) ) - -namespace squish { - -#define VEC4_CONST( X ) Vec4( X ) - -class Vec4 -{ -public: - typedef Vec4 const& Arg; - - Vec4() {} - - explicit Vec4( __m128 v ) : m_v( v ) {} - - Vec4( Vec4 const& arg ) : m_v( arg.m_v ) {} - - Vec4& operator=( Vec4 const& arg ) - { - m_v = arg.m_v; - return *this; - } - - explicit Vec4( float s ) : m_v( _mm_set1_ps( s ) ) {} - - Vec4( float x, float y, float z, float w ) : m_v( _mm_setr_ps( x, y, z, w ) ) {} - - Vec3 GetVec3() const - { -#ifdef __GNUC__ - __attribute__ ((__aligned__ (16))) float c[4]; -#else - __declspec(align(16)) float c[4]; -#endif - _mm_store_ps( c, m_v ); - return Vec3( c[0], c[1], c[2] ); - } - - Vec4 SplatX() const { return Vec4( _mm_shuffle_ps( m_v, m_v, SQUISH_SSE_SPLAT( 0 ) ) ); } - Vec4 SplatY() const { return Vec4( _mm_shuffle_ps( m_v, m_v, SQUISH_SSE_SPLAT( 1 ) ) ); } - Vec4 SplatZ() const { return Vec4( _mm_shuffle_ps( m_v, m_v, SQUISH_SSE_SPLAT( 2 ) ) ); } - Vec4 SplatW() const { return Vec4( _mm_shuffle_ps( m_v, m_v, SQUISH_SSE_SPLAT( 3 ) ) ); } - - Vec4& operator+=( Arg v ) - { - m_v = _mm_add_ps( m_v, v.m_v ); - return *this; - } - - Vec4& operator-=( Arg v ) - { - m_v = _mm_sub_ps( m_v, v.m_v ); - return *this; - } - - Vec4& operator*=( Arg v ) - { - m_v = _mm_mul_ps( m_v, v.m_v ); - return *this; - } - - friend Vec4 operator+( Vec4::Arg left, Vec4::Arg right ) - { - return Vec4( _mm_add_ps( left.m_v, right.m_v ) ); - } - - friend Vec4 operator-( Vec4::Arg left, Vec4::Arg right ) - { - return Vec4( _mm_sub_ps( left.m_v, right.m_v ) ); - } - - friend Vec4 operator*( Vec4::Arg left, Vec4::Arg right ) - { - return Vec4( _mm_mul_ps( left.m_v, right.m_v ) ); - } - - //! Returns a*b + c - friend Vec4 MultiplyAdd( Vec4::Arg a, Vec4::Arg b, Vec4::Arg c ) - { - return Vec4( _mm_add_ps( _mm_mul_ps( a.m_v, b.m_v ), c.m_v ) ); - } - - //! Returns -( a*b - c ) - friend Vec4 NegativeMultiplySubtract( Vec4::Arg a, Vec4::Arg b, Vec4::Arg c ) - { - return Vec4( _mm_sub_ps( c.m_v, _mm_mul_ps( a.m_v, b.m_v ) ) ); - } - - friend Vec4 Reciprocal( Vec4::Arg v ) - { - // get the reciprocal estimate - __m128 estimate = _mm_rcp_ps( v.m_v ); - - // one round of Newton-Rhaphson refinement - __m128 diff = _mm_sub_ps( _mm_set1_ps( 1.0f ), _mm_mul_ps( estimate, v.m_v ) ); - return Vec4( _mm_add_ps( _mm_mul_ps( diff, estimate ), estimate ) ); - } - - friend Vec4 Min( Vec4::Arg left, Vec4::Arg right ) - { - return Vec4( _mm_min_ps( left.m_v, right.m_v ) ); - } - - friend Vec4 Max( Vec4::Arg left, Vec4::Arg right ) - { - return Vec4( _mm_max_ps( left.m_v, right.m_v ) ); - } - - friend Vec4 Truncate( Vec4::Arg v ) - { -#if ( SQUISH_USE_SSE == 1 ) - // convert to ints - __m128 input = v.m_v; - __m64 lo = _mm_cvttps_pi32( input ); - __m64 hi = _mm_cvttps_pi32( _mm_movehl_ps( input, input ) ); - - // convert to floats - __m128 part = _mm_movelh_ps( input, _mm_cvtpi32_ps( input, hi ) ); - __m128 truncated = _mm_cvtpi32_ps( part, lo ); - - // clear out the MMX multimedia state to allow FP calls later - _mm_empty(); - return Vec4( truncated ); -#else - // use SSE2 instructions - return Vec4( _mm_cvtepi32_ps( _mm_cvttps_epi32( v.m_v ) ) ); -#endif - } - - friend bool CompareAnyLessThan( Vec4::Arg left, Vec4::Arg right ) - { - __m128 bits = _mm_cmplt_ps( left.m_v, right.m_v ); - int value = _mm_movemask_ps( bits ); - return value != 0; - } - -private: - __m128 m_v; -}; - -} // namespace squish - -#endif // ndef SQUISH_SIMD_SSE_H diff --git a/thirdparty/squish/simd_ve.h b/thirdparty/squish/simd_ve.h deleted file mode 100644 index 08a1537503..0000000000 --- a/thirdparty/squish/simd_ve.h +++ /dev/null @@ -1,166 +0,0 @@ -/* ----------------------------------------------------------------------------- - - Copyright (c) 2006 Simon Brown si@sjbrown.co.uk - - 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 SQUISH_SIMD_VE_H -#define SQUISH_SIMD_VE_H - -#include <altivec.h> -#undef bool - -namespace squish { - -#define VEC4_CONST( X ) Vec4( ( vector float ){ X } ) - -class Vec4 -{ -public: - typedef Vec4 Arg; - - Vec4() {} - - explicit Vec4( vector float v ) : m_v( v ) {} - - Vec4( Vec4 const& arg ) : m_v( arg.m_v ) {} - - Vec4& operator=( Vec4 const& arg ) - { - m_v = arg.m_v; - return *this; - } - - explicit Vec4( float s ) - { - union { vector float v; float c[4]; } u; - u.c[0] = s; - u.c[1] = s; - u.c[2] = s; - u.c[3] = s; - m_v = u.v; - } - - Vec4( float x, float y, float z, float w ) - { - union { vector float v; float c[4]; } u; - u.c[0] = x; - u.c[1] = y; - u.c[2] = z; - u.c[3] = w; - m_v = u.v; - } - - Vec3 GetVec3() const - { - union { vector float v; float c[4]; } u; - u.v = m_v; - return Vec3( u.c[0], u.c[1], u.c[2] ); - } - - Vec4 SplatX() const { return Vec4( vec_splat( m_v, 0 ) ); } - Vec4 SplatY() const { return Vec4( vec_splat( m_v, 1 ) ); } - Vec4 SplatZ() const { return Vec4( vec_splat( m_v, 2 ) ); } - Vec4 SplatW() const { return Vec4( vec_splat( m_v, 3 ) ); } - - Vec4& operator+=( Arg v ) - { - m_v = vec_add( m_v, v.m_v ); - return *this; - } - - Vec4& operator-=( Arg v ) - { - m_v = vec_sub( m_v, v.m_v ); - return *this; - } - - Vec4& operator*=( Arg v ) - { - m_v = vec_madd( m_v, v.m_v, ( vector float ){ -0.0f } ); - return *this; - } - - friend Vec4 operator+( Vec4::Arg left, Vec4::Arg right ) - { - return Vec4( vec_add( left.m_v, right.m_v ) ); - } - - friend Vec4 operator-( Vec4::Arg left, Vec4::Arg right ) - { - return Vec4( vec_sub( left.m_v, right.m_v ) ); - } - - friend Vec4 operator*( Vec4::Arg left, Vec4::Arg right ) - { - return Vec4( vec_madd( left.m_v, right.m_v, ( vector float ){ -0.0f } ) ); - } - - //! Returns a*b + c - friend Vec4 MultiplyAdd( Vec4::Arg a, Vec4::Arg b, Vec4::Arg c ) - { - return Vec4( vec_madd( a.m_v, b.m_v, c.m_v ) ); - } - - //! Returns -( a*b - c ) - friend Vec4 NegativeMultiplySubtract( Vec4::Arg a, Vec4::Arg b, Vec4::Arg c ) - { - return Vec4( vec_nmsub( a.m_v, b.m_v, c.m_v ) ); - } - - friend Vec4 Reciprocal( Vec4::Arg v ) - { - // get the reciprocal estimate - vector float estimate = vec_re( v.m_v ); - - // one round of Newton-Rhaphson refinement - vector float diff = vec_nmsub( estimate, v.m_v, ( vector float ){ 1.0f } ); - return Vec4( vec_madd( diff, estimate, estimate ) ); - } - - friend Vec4 Min( Vec4::Arg left, Vec4::Arg right ) - { - return Vec4( vec_min( left.m_v, right.m_v ) ); - } - - friend Vec4 Max( Vec4::Arg left, Vec4::Arg right ) - { - return Vec4( vec_max( left.m_v, right.m_v ) ); - } - - friend Vec4 Truncate( Vec4::Arg v ) - { - return Vec4( vec_trunc( v.m_v ) ); - } - - friend bool CompareAnyLessThan( Vec4::Arg left, Vec4::Arg right ) - { - return vec_any_lt( left.m_v, right.m_v ) != 0; - } - -private: - vector float m_v; -}; - -} // namespace squish - -#endif // ndef SQUISH_SIMD_VE_H diff --git a/thirdparty/squish/singlecolourfit.cpp b/thirdparty/squish/singlecolourfit.cpp deleted file mode 100644 index cef0ebc410..0000000000 --- a/thirdparty/squish/singlecolourfit.cpp +++ /dev/null @@ -1,172 +0,0 @@ -/* ----------------------------------------------------------------------------- - - Copyright (c) 2006 Simon Brown si@sjbrown.co.uk - - 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 "singlecolourfit.h" -#include "colourset.h" -#include "colourblock.h" - -namespace squish { - -struct SourceBlock -{ - u8 start; - u8 end; - u8 error; -}; - -struct SingleColourLookup -{ - SourceBlock sources[2]; -}; - -#include "singlecolourlookup.inl" - -static int FloatToInt( float a, int limit ) -{ - // use ANSI round-to-zero behaviour to get round-to-nearest - int i = ( int )( a + 0.5f ); - - // clamp to the limit - if( i < 0 ) - i = 0; - else if( i > limit ) - i = limit; - - // done - return i; -} - -SingleColourFit::SingleColourFit( ColourSet const* colours, int flags ) - : ColourFit( colours, flags ) -{ - // grab the single colour - Vec3 const* values = m_colours->GetPoints(); - m_colour[0] = ( u8 )FloatToInt( 255.0f*values->X(), 255 ); - m_colour[1] = ( u8 )FloatToInt( 255.0f*values->Y(), 255 ); - m_colour[2] = ( u8 )FloatToInt( 255.0f*values->Z(), 255 ); - - // initialise the best error - m_besterror = INT_MAX; -} - -void SingleColourFit::Compress3( void* block ) -{ - // build the table of lookups - SingleColourLookup const* const lookups[] = - { - lookup_5_3, - lookup_6_3, - lookup_5_3 - }; - - // find the best end-points and index - ComputeEndPoints( lookups ); - - // build the block if we win - if( m_error < m_besterror ) - { - // remap the indices - u8 indices[16]; - m_colours->RemapIndices( &m_index, indices ); - - // save the block - WriteColourBlock3( m_start, m_end, indices, block ); - - // save the error - m_besterror = m_error; - } -} - -void SingleColourFit::Compress4( void* block ) -{ - // build the table of lookups - SingleColourLookup const* const lookups[] = - { - lookup_5_4, - lookup_6_4, - lookup_5_4 - }; - - // find the best end-points and index - ComputeEndPoints( lookups ); - - // build the block if we win - if( m_error < m_besterror ) - { - // remap the indices - u8 indices[16]; - m_colours->RemapIndices( &m_index, indices ); - - // save the block - WriteColourBlock4( m_start, m_end, indices, block ); - - // save the error - m_besterror = m_error; - } -} - -void SingleColourFit::ComputeEndPoints( SingleColourLookup const* const* lookups ) -{ - // check each index combination (endpoint or intermediate) - m_error = INT_MAX; - for( int index = 0; index < 2; ++index ) - { - // check the error for this codebook index - SourceBlock const* sources[3]; - int error = 0; - for( int channel = 0; channel < 3; ++channel ) - { - // grab the lookup table and index for this channel - SingleColourLookup const* lookup = lookups[channel]; - int target = m_colour[channel]; - - // store a pointer to the source for this channel - sources[channel] = lookup[target].sources + index; - - // accumulate the error - int diff = sources[channel]->error; - error += diff*diff; - } - - // keep it if the error is lower - if( error < m_error ) - { - m_start = Vec3( - ( float )sources[0]->start/31.0f, - ( float )sources[1]->start/63.0f, - ( float )sources[2]->start/31.0f - ); - m_end = Vec3( - ( float )sources[0]->end/31.0f, - ( float )sources[1]->end/63.0f, - ( float )sources[2]->end/31.0f - ); - m_index = ( u8 )( 2*index ); - m_error = error; - } - } -} - -} // namespace squish diff --git a/thirdparty/squish/singlecolourfit.h b/thirdparty/squish/singlecolourfit.h deleted file mode 100644 index 974ce77256..0000000000 --- a/thirdparty/squish/singlecolourfit.h +++ /dev/null @@ -1,58 +0,0 @@ -/* ----------------------------------------------------------------------------- - - Copyright (c) 2006 Simon Brown si@sjbrown.co.uk - - 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 SQUISH_SINGLECOLOURFIT_H -#define SQUISH_SINGLECOLOURFIT_H - -#include "squish.h" -#include "colourfit.h" - -namespace squish { - -class ColourSet; -struct SingleColourLookup; - -class SingleColourFit : public ColourFit -{ -public: - SingleColourFit( ColourSet const* colours, int flags ); - -private: - virtual void Compress3( void* block ); - virtual void Compress4( void* block ); - - void ComputeEndPoints( SingleColourLookup const* const* lookups ); - - u8 m_colour[3]; - Vec3 m_start; - Vec3 m_end; - u8 m_index; - int m_error; - int m_besterror; -}; - -} // namespace squish - -#endif // ndef SQUISH_SINGLECOLOURFIT_H diff --git a/thirdparty/squish/singlecolourlookup.inl b/thirdparty/squish/singlecolourlookup.inl deleted file mode 100644 index 5b44a1e5e6..0000000000 --- a/thirdparty/squish/singlecolourlookup.inl +++ /dev/null @@ -1,1064 +0,0 @@ -/* ----------------------------------------------------------------------------- - - Copyright (c) 2006 Simon Brown si@sjbrown.co.uk - - 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. - - -------------------------------------------------------------------------- */ - -static SingleColourLookup const lookup_5_3[] = -{ - { { { 0, 0, 0 }, { 0, 0, 0 } } }, - { { { 0, 0, 1 }, { 0, 0, 1 } } }, - { { { 0, 0, 2 }, { 0, 0, 2 } } }, - { { { 0, 0, 3 }, { 0, 1, 1 } } }, - { { { 0, 0, 4 }, { 0, 1, 0 } } }, - { { { 1, 0, 3 }, { 0, 1, 1 } } }, - { { { 1, 0, 2 }, { 0, 1, 2 } } }, - { { { 1, 0, 1 }, { 0, 2, 1 } } }, - { { { 1, 0, 0 }, { 0, 2, 0 } } }, - { { { 1, 0, 1 }, { 0, 2, 1 } } }, - { { { 1, 0, 2 }, { 0, 2, 2 } } }, - { { { 1, 0, 3 }, { 0, 3, 1 } } }, - { { { 1, 0, 4 }, { 0, 3, 0 } } }, - { { { 2, 0, 3 }, { 0, 3, 1 } } }, - { { { 2, 0, 2 }, { 0, 3, 2 } } }, - { { { 2, 0, 1 }, { 0, 4, 1 } } }, - { { { 2, 0, 0 }, { 0, 4, 0 } } }, - { { { 2, 0, 1 }, { 0, 4, 1 } } }, - { { { 2, 0, 2 }, { 0, 4, 2 } } }, - { { { 2, 0, 3 }, { 0, 5, 1 } } }, - { { { 2, 0, 4 }, { 0, 5, 0 } } }, - { { { 3, 0, 3 }, { 0, 5, 1 } } }, - { { { 3, 0, 2 }, { 0, 5, 2 } } }, - { { { 3, 0, 1 }, { 0, 6, 1 } } }, - { { { 3, 0, 0 }, { 0, 6, 0 } } }, - { { { 3, 0, 1 }, { 0, 6, 1 } } }, - { { { 3, 0, 2 }, { 0, 6, 2 } } }, - { { { 3, 0, 3 }, { 0, 7, 1 } } }, - { { { 3, 0, 4 }, { 0, 7, 0 } } }, - { { { 4, 0, 4 }, { 0, 7, 1 } } }, - { { { 4, 0, 3 }, { 0, 7, 2 } } }, - { { { 4, 0, 2 }, { 1, 7, 1 } } }, - { { { 4, 0, 1 }, { 1, 7, 0 } } }, - { { { 4, 0, 0 }, { 0, 8, 0 } } }, - { { { 4, 0, 1 }, { 0, 8, 1 } } }, - { { { 4, 0, 2 }, { 2, 7, 1 } } }, - { { { 4, 0, 3 }, { 2, 7, 0 } } }, - { { { 4, 0, 4 }, { 0, 9, 0 } } }, - { { { 5, 0, 3 }, { 0, 9, 1 } } }, - { { { 5, 0, 2 }, { 3, 7, 1 } } }, - { { { 5, 0, 1 }, { 3, 7, 0 } } }, - { { { 5, 0, 0 }, { 0, 10, 0 } } }, - { { { 5, 0, 1 }, { 0, 10, 1 } } }, - { { { 5, 0, 2 }, { 0, 10, 2 } } }, - { { { 5, 0, 3 }, { 0, 11, 1 } } }, - { { { 5, 0, 4 }, { 0, 11, 0 } } }, - { { { 6, 0, 3 }, { 0, 11, 1 } } }, - { { { 6, 0, 2 }, { 0, 11, 2 } } }, - { { { 6, 0, 1 }, { 0, 12, 1 } } }, - { { { 6, 0, 0 }, { 0, 12, 0 } } }, - { { { 6, 0, 1 }, { 0, 12, 1 } } }, - { { { 6, 0, 2 }, { 0, 12, 2 } } }, - { { { 6, 0, 3 }, { 0, 13, 1 } } }, - { { { 6, 0, 4 }, { 0, 13, 0 } } }, - { { { 7, 0, 3 }, { 0, 13, 1 } } }, - { { { 7, 0, 2 }, { 0, 13, 2 } } }, - { { { 7, 0, 1 }, { 0, 14, 1 } } }, - { { { 7, 0, 0 }, { 0, 14, 0 } } }, - { { { 7, 0, 1 }, { 0, 14, 1 } } }, - { { { 7, 0, 2 }, { 0, 14, 2 } } }, - { { { 7, 0, 3 }, { 0, 15, 1 } } }, - { { { 7, 0, 4 }, { 0, 15, 0 } } }, - { { { 8, 0, 4 }, { 0, 15, 1 } } }, - { { { 8, 0, 3 }, { 0, 15, 2 } } }, - { { { 8, 0, 2 }, { 1, 15, 1 } } }, - { { { 8, 0, 1 }, { 1, 15, 0 } } }, - { { { 8, 0, 0 }, { 0, 16, 0 } } }, - { { { 8, 0, 1 }, { 0, 16, 1 } } }, - { { { 8, 0, 2 }, { 2, 15, 1 } } }, - { { { 8, 0, 3 }, { 2, 15, 0 } } }, - { { { 8, 0, 4 }, { 0, 17, 0 } } }, - { { { 9, 0, 3 }, { 0, 17, 1 } } }, - { { { 9, 0, 2 }, { 3, 15, 1 } } }, - { { { 9, 0, 1 }, { 3, 15, 0 } } }, - { { { 9, 0, 0 }, { 0, 18, 0 } } }, - { { { 9, 0, 1 }, { 0, 18, 1 } } }, - { { { 9, 0, 2 }, { 0, 18, 2 } } }, - { { { 9, 0, 3 }, { 0, 19, 1 } } }, - { { { 9, 0, 4 }, { 0, 19, 0 } } }, - { { { 10, 0, 3 }, { 0, 19, 1 } } }, - { { { 10, 0, 2 }, { 0, 19, 2 } } }, - { { { 10, 0, 1 }, { 0, 20, 1 } } }, - { { { 10, 0, 0 }, { 0, 20, 0 } } }, - { { { 10, 0, 1 }, { 0, 20, 1 } } }, - { { { 10, 0, 2 }, { 0, 20, 2 } } }, - { { { 10, 0, 3 }, { 0, 21, 1 } } }, - { { { 10, 0, 4 }, { 0, 21, 0 } } }, - { { { 11, 0, 3 }, { 0, 21, 1 } } }, - { { { 11, 0, 2 }, { 0, 21, 2 } } }, - { { { 11, 0, 1 }, { 0, 22, 1 } } }, - { { { 11, 0, 0 }, { 0, 22, 0 } } }, - { { { 11, 0, 1 }, { 0, 22, 1 } } }, - { { { 11, 0, 2 }, { 0, 22, 2 } } }, - { { { 11, 0, 3 }, { 0, 23, 1 } } }, - { { { 11, 0, 4 }, { 0, 23, 0 } } }, - { { { 12, 0, 4 }, { 0, 23, 1 } } }, - { { { 12, 0, 3 }, { 0, 23, 2 } } }, - { { { 12, 0, 2 }, { 1, 23, 1 } } }, - { { { 12, 0, 1 }, { 1, 23, 0 } } }, - { { { 12, 0, 0 }, { 0, 24, 0 } } }, - { { { 12, 0, 1 }, { 0, 24, 1 } } }, - { { { 12, 0, 2 }, { 2, 23, 1 } } }, - { { { 12, 0, 3 }, { 2, 23, 0 } } }, - { { { 12, 0, 4 }, { 0, 25, 0 } } }, - { { { 13, 0, 3 }, { 0, 25, 1 } } }, - { { { 13, 0, 2 }, { 3, 23, 1 } } }, - { { { 13, 0, 1 }, { 3, 23, 0 } } }, - { { { 13, 0, 0 }, { 0, 26, 0 } } }, - { { { 13, 0, 1 }, { 0, 26, 1 } } }, - { { { 13, 0, 2 }, { 0, 26, 2 } } }, - { { { 13, 0, 3 }, { 0, 27, 1 } } }, - { { { 13, 0, 4 }, { 0, 27, 0 } } }, - { { { 14, 0, 3 }, { 0, 27, 1 } } }, - { { { 14, 0, 2 }, { 0, 27, 2 } } }, - { { { 14, 0, 1 }, { 0, 28, 1 } } }, - { { { 14, 0, 0 }, { 0, 28, 0 } } }, - { { { 14, 0, 1 }, { 0, 28, 1 } } }, - { { { 14, 0, 2 }, { 0, 28, 2 } } }, - { { { 14, 0, 3 }, { 0, 29, 1 } } }, - { { { 14, 0, 4 }, { 0, 29, 0 } } }, - { { { 15, 0, 3 }, { 0, 29, 1 } } }, - { { { 15, 0, 2 }, { 0, 29, 2 } } }, - { { { 15, 0, 1 }, { 0, 30, 1 } } }, - { { { 15, 0, 0 }, { 0, 30, 0 } } }, - { { { 15, 0, 1 }, { 0, 30, 1 } } }, - { { { 15, 0, 2 }, { 0, 30, 2 } } }, - { { { 15, 0, 3 }, { 0, 31, 1 } } }, - { { { 15, 0, 4 }, { 0, 31, 0 } } }, - { { { 16, 0, 4 }, { 0, 31, 1 } } }, - { { { 16, 0, 3 }, { 0, 31, 2 } } }, - { { { 16, 0, 2 }, { 1, 31, 1 } } }, - { { { 16, 0, 1 }, { 1, 31, 0 } } }, - { { { 16, 0, 0 }, { 4, 28, 0 } } }, - { { { 16, 0, 1 }, { 4, 28, 1 } } }, - { { { 16, 0, 2 }, { 2, 31, 1 } } }, - { { { 16, 0, 3 }, { 2, 31, 0 } } }, - { { { 16, 0, 4 }, { 4, 29, 0 } } }, - { { { 17, 0, 3 }, { 4, 29, 1 } } }, - { { { 17, 0, 2 }, { 3, 31, 1 } } }, - { { { 17, 0, 1 }, { 3, 31, 0 } } }, - { { { 17, 0, 0 }, { 4, 30, 0 } } }, - { { { 17, 0, 1 }, { 4, 30, 1 } } }, - { { { 17, 0, 2 }, { 4, 30, 2 } } }, - { { { 17, 0, 3 }, { 4, 31, 1 } } }, - { { { 17, 0, 4 }, { 4, 31, 0 } } }, - { { { 18, 0, 3 }, { 4, 31, 1 } } }, - { { { 18, 0, 2 }, { 4, 31, 2 } } }, - { { { 18, 0, 1 }, { 5, 31, 1 } } }, - { { { 18, 0, 0 }, { 5, 31, 0 } } }, - { { { 18, 0, 1 }, { 5, 31, 1 } } }, - { { { 18, 0, 2 }, { 5, 31, 2 } } }, - { { { 18, 0, 3 }, { 6, 31, 1 } } }, - { { { 18, 0, 4 }, { 6, 31, 0 } } }, - { { { 19, 0, 3 }, { 6, 31, 1 } } }, - { { { 19, 0, 2 }, { 6, 31, 2 } } }, - { { { 19, 0, 1 }, { 7, 31, 1 } } }, - { { { 19, 0, 0 }, { 7, 31, 0 } } }, - { { { 19, 0, 1 }, { 7, 31, 1 } } }, - { { { 19, 0, 2 }, { 7, 31, 2 } } }, - { { { 19, 0, 3 }, { 8, 31, 1 } } }, - { { { 19, 0, 4 }, { 8, 31, 0 } } }, - { { { 20, 0, 4 }, { 8, 31, 1 } } }, - { { { 20, 0, 3 }, { 8, 31, 2 } } }, - { { { 20, 0, 2 }, { 9, 31, 1 } } }, - { { { 20, 0, 1 }, { 9, 31, 0 } } }, - { { { 20, 0, 0 }, { 12, 28, 0 } } }, - { { { 20, 0, 1 }, { 12, 28, 1 } } }, - { { { 20, 0, 2 }, { 10, 31, 1 } } }, - { { { 20, 0, 3 }, { 10, 31, 0 } } }, - { { { 20, 0, 4 }, { 12, 29, 0 } } }, - { { { 21, 0, 3 }, { 12, 29, 1 } } }, - { { { 21, 0, 2 }, { 11, 31, 1 } } }, - { { { 21, 0, 1 }, { 11, 31, 0 } } }, - { { { 21, 0, 0 }, { 12, 30, 0 } } }, - { { { 21, 0, 1 }, { 12, 30, 1 } } }, - { { { 21, 0, 2 }, { 12, 30, 2 } } }, - { { { 21, 0, 3 }, { 12, 31, 1 } } }, - { { { 21, 0, 4 }, { 12, 31, 0 } } }, - { { { 22, 0, 3 }, { 12, 31, 1 } } }, - { { { 22, 0, 2 }, { 12, 31, 2 } } }, - { { { 22, 0, 1 }, { 13, 31, 1 } } }, - { { { 22, 0, 0 }, { 13, 31, 0 } } }, - { { { 22, 0, 1 }, { 13, 31, 1 } } }, - { { { 22, 0, 2 }, { 13, 31, 2 } } }, - { { { 22, 0, 3 }, { 14, 31, 1 } } }, - { { { 22, 0, 4 }, { 14, 31, 0 } } }, - { { { 23, 0, 3 }, { 14, 31, 1 } } }, - { { { 23, 0, 2 }, { 14, 31, 2 } } }, - { { { 23, 0, 1 }, { 15, 31, 1 } } }, - { { { 23, 0, 0 }, { 15, 31, 0 } } }, - { { { 23, 0, 1 }, { 15, 31, 1 } } }, - { { { 23, 0, 2 }, { 15, 31, 2 } } }, - { { { 23, 0, 3 }, { 16, 31, 1 } } }, - { { { 23, 0, 4 }, { 16, 31, 0 } } }, - { { { 24, 0, 4 }, { 16, 31, 1 } } }, - { { { 24, 0, 3 }, { 16, 31, 2 } } }, - { { { 24, 0, 2 }, { 17, 31, 1 } } }, - { { { 24, 0, 1 }, { 17, 31, 0 } } }, - { { { 24, 0, 0 }, { 20, 28, 0 } } }, - { { { 24, 0, 1 }, { 20, 28, 1 } } }, - { { { 24, 0, 2 }, { 18, 31, 1 } } }, - { { { 24, 0, 3 }, { 18, 31, 0 } } }, - { { { 24, 0, 4 }, { 20, 29, 0 } } }, - { { { 25, 0, 3 }, { 20, 29, 1 } } }, - { { { 25, 0, 2 }, { 19, 31, 1 } } }, - { { { 25, 0, 1 }, { 19, 31, 0 } } }, - { { { 25, 0, 0 }, { 20, 30, 0 } } }, - { { { 25, 0, 1 }, { 20, 30, 1 } } }, - { { { 25, 0, 2 }, { 20, 30, 2 } } }, - { { { 25, 0, 3 }, { 20, 31, 1 } } }, - { { { 25, 0, 4 }, { 20, 31, 0 } } }, - { { { 26, 0, 3 }, { 20, 31, 1 } } }, - { { { 26, 0, 2 }, { 20, 31, 2 } } }, - { { { 26, 0, 1 }, { 21, 31, 1 } } }, - { { { 26, 0, 0 }, { 21, 31, 0 } } }, - { { { 26, 0, 1 }, { 21, 31, 1 } } }, - { { { 26, 0, 2 }, { 21, 31, 2 } } }, - { { { 26, 0, 3 }, { 22, 31, 1 } } }, - { { { 26, 0, 4 }, { 22, 31, 0 } } }, - { { { 27, 0, 3 }, { 22, 31, 1 } } }, - { { { 27, 0, 2 }, { 22, 31, 2 } } }, - { { { 27, 0, 1 }, { 23, 31, 1 } } }, - { { { 27, 0, 0 }, { 23, 31, 0 } } }, - { { { 27, 0, 1 }, { 23, 31, 1 } } }, - { { { 27, 0, 2 }, { 23, 31, 2 } } }, - { { { 27, 0, 3 }, { 24, 31, 1 } } }, - { { { 27, 0, 4 }, { 24, 31, 0 } } }, - { { { 28, 0, 4 }, { 24, 31, 1 } } }, - { { { 28, 0, 3 }, { 24, 31, 2 } } }, - { { { 28, 0, 2 }, { 25, 31, 1 } } }, - { { { 28, 0, 1 }, { 25, 31, 0 } } }, - { { { 28, 0, 0 }, { 28, 28, 0 } } }, - { { { 28, 0, 1 }, { 28, 28, 1 } } }, - { { { 28, 0, 2 }, { 26, 31, 1 } } }, - { { { 28, 0, 3 }, { 26, 31, 0 } } }, - { { { 28, 0, 4 }, { 28, 29, 0 } } }, - { { { 29, 0, 3 }, { 28, 29, 1 } } }, - { { { 29, 0, 2 }, { 27, 31, 1 } } }, - { { { 29, 0, 1 }, { 27, 31, 0 } } }, - { { { 29, 0, 0 }, { 28, 30, 0 } } }, - { { { 29, 0, 1 }, { 28, 30, 1 } } }, - { { { 29, 0, 2 }, { 28, 30, 2 } } }, - { { { 29, 0, 3 }, { 28, 31, 1 } } }, - { { { 29, 0, 4 }, { 28, 31, 0 } } }, - { { { 30, 0, 3 }, { 28, 31, 1 } } }, - { { { 30, 0, 2 }, { 28, 31, 2 } } }, - { { { 30, 0, 1 }, { 29, 31, 1 } } }, - { { { 30, 0, 0 }, { 29, 31, 0 } } }, - { { { 30, 0, 1 }, { 29, 31, 1 } } }, - { { { 30, 0, 2 }, { 29, 31, 2 } } }, - { { { 30, 0, 3 }, { 30, 31, 1 } } }, - { { { 30, 0, 4 }, { 30, 31, 0 } } }, - { { { 31, 0, 3 }, { 30, 31, 1 } } }, - { { { 31, 0, 2 }, { 30, 31, 2 } } }, - { { { 31, 0, 1 }, { 31, 31, 1 } } }, - { { { 31, 0, 0 }, { 31, 31, 0 } } } -}; - -static SingleColourLookup const lookup_6_3[] = -{ - { { { 0, 0, 0 }, { 0, 0, 0 } } }, - { { { 0, 0, 1 }, { 0, 1, 1 } } }, - { { { 0, 0, 2 }, { 0, 1, 0 } } }, - { { { 1, 0, 1 }, { 0, 2, 1 } } }, - { { { 1, 0, 0 }, { 0, 2, 0 } } }, - { { { 1, 0, 1 }, { 0, 3, 1 } } }, - { { { 1, 0, 2 }, { 0, 3, 0 } } }, - { { { 2, 0, 1 }, { 0, 4, 1 } } }, - { { { 2, 0, 0 }, { 0, 4, 0 } } }, - { { { 2, 0, 1 }, { 0, 5, 1 } } }, - { { { 2, 0, 2 }, { 0, 5, 0 } } }, - { { { 3, 0, 1 }, { 0, 6, 1 } } }, - { { { 3, 0, 0 }, { 0, 6, 0 } } }, - { { { 3, 0, 1 }, { 0, 7, 1 } } }, - { { { 3, 0, 2 }, { 0, 7, 0 } } }, - { { { 4, 0, 1 }, { 0, 8, 1 } } }, - { { { 4, 0, 0 }, { 0, 8, 0 } } }, - { { { 4, 0, 1 }, { 0, 9, 1 } } }, - { { { 4, 0, 2 }, { 0, 9, 0 } } }, - { { { 5, 0, 1 }, { 0, 10, 1 } } }, - { { { 5, 0, 0 }, { 0, 10, 0 } } }, - { { { 5, 0, 1 }, { 0, 11, 1 } } }, - { { { 5, 0, 2 }, { 0, 11, 0 } } }, - { { { 6, 0, 1 }, { 0, 12, 1 } } }, - { { { 6, 0, 0 }, { 0, 12, 0 } } }, - { { { 6, 0, 1 }, { 0, 13, 1 } } }, - { { { 6, 0, 2 }, { 0, 13, 0 } } }, - { { { 7, 0, 1 }, { 0, 14, 1 } } }, - { { { 7, 0, 0 }, { 0, 14, 0 } } }, - { { { 7, 0, 1 }, { 0, 15, 1 } } }, - { { { 7, 0, 2 }, { 0, 15, 0 } } }, - { { { 8, 0, 1 }, { 0, 16, 1 } } }, - { { { 8, 0, 0 }, { 0, 16, 0 } } }, - { { { 8, 0, 1 }, { 0, 17, 1 } } }, - { { { 8, 0, 2 }, { 0, 17, 0 } } }, - { { { 9, 0, 1 }, { 0, 18, 1 } } }, - { { { 9, 0, 0 }, { 0, 18, 0 } } }, - { { { 9, 0, 1 }, { 0, 19, 1 } } }, - { { { 9, 0, 2 }, { 0, 19, 0 } } }, - { { { 10, 0, 1 }, { 0, 20, 1 } } }, - { { { 10, 0, 0 }, { 0, 20, 0 } } }, - { { { 10, 0, 1 }, { 0, 21, 1 } } }, - { { { 10, 0, 2 }, { 0, 21, 0 } } }, - { { { 11, 0, 1 }, { 0, 22, 1 } } }, - { { { 11, 0, 0 }, { 0, 22, 0 } } }, - { { { 11, 0, 1 }, { 0, 23, 1 } } }, - { { { 11, 0, 2 }, { 0, 23, 0 } } }, - { { { 12, 0, 1 }, { 0, 24, 1 } } }, - { { { 12, 0, 0 }, { 0, 24, 0 } } }, - { { { 12, 0, 1 }, { 0, 25, 1 } } }, - { { { 12, 0, 2 }, { 0, 25, 0 } } }, - { { { 13, 0, 1 }, { 0, 26, 1 } } }, - { { { 13, 0, 0 }, { 0, 26, 0 } } }, - { { { 13, 0, 1 }, { 0, 27, 1 } } }, - { { { 13, 0, 2 }, { 0, 27, 0 } } }, - { { { 14, 0, 1 }, { 0, 28, 1 } } }, - { { { 14, 0, 0 }, { 0, 28, 0 } } }, - { { { 14, 0, 1 }, { 0, 29, 1 } } }, - { { { 14, 0, 2 }, { 0, 29, 0 } } }, - { { { 15, 0, 1 }, { 0, 30, 1 } } }, - { { { 15, 0, 0 }, { 0, 30, 0 } } }, - { { { 15, 0, 1 }, { 0, 31, 1 } } }, - { { { 15, 0, 2 }, { 0, 31, 0 } } }, - { { { 16, 0, 2 }, { 1, 31, 1 } } }, - { { { 16, 0, 1 }, { 1, 31, 0 } } }, - { { { 16, 0, 0 }, { 0, 32, 0 } } }, - { { { 16, 0, 1 }, { 2, 31, 0 } } }, - { { { 16, 0, 2 }, { 0, 33, 0 } } }, - { { { 17, 0, 1 }, { 3, 31, 0 } } }, - { { { 17, 0, 0 }, { 0, 34, 0 } } }, - { { { 17, 0, 1 }, { 4, 31, 0 } } }, - { { { 17, 0, 2 }, { 0, 35, 0 } } }, - { { { 18, 0, 1 }, { 5, 31, 0 } } }, - { { { 18, 0, 0 }, { 0, 36, 0 } } }, - { { { 18, 0, 1 }, { 6, 31, 0 } } }, - { { { 18, 0, 2 }, { 0, 37, 0 } } }, - { { { 19, 0, 1 }, { 7, 31, 0 } } }, - { { { 19, 0, 0 }, { 0, 38, 0 } } }, - { { { 19, 0, 1 }, { 8, 31, 0 } } }, - { { { 19, 0, 2 }, { 0, 39, 0 } } }, - { { { 20, 0, 1 }, { 9, 31, 0 } } }, - { { { 20, 0, 0 }, { 0, 40, 0 } } }, - { { { 20, 0, 1 }, { 10, 31, 0 } } }, - { { { 20, 0, 2 }, { 0, 41, 0 } } }, - { { { 21, 0, 1 }, { 11, 31, 0 } } }, - { { { 21, 0, 0 }, { 0, 42, 0 } } }, - { { { 21, 0, 1 }, { 12, 31, 0 } } }, - { { { 21, 0, 2 }, { 0, 43, 0 } } }, - { { { 22, 0, 1 }, { 13, 31, 0 } } }, - { { { 22, 0, 0 }, { 0, 44, 0 } } }, - { { { 22, 0, 1 }, { 14, 31, 0 } } }, - { { { 22, 0, 2 }, { 0, 45, 0 } } }, - { { { 23, 0, 1 }, { 15, 31, 0 } } }, - { { { 23, 0, 0 }, { 0, 46, 0 } } }, - { { { 23, 0, 1 }, { 0, 47, 1 } } }, - { { { 23, 0, 2 }, { 0, 47, 0 } } }, - { { { 24, 0, 1 }, { 0, 48, 1 } } }, - { { { 24, 0, 0 }, { 0, 48, 0 } } }, - { { { 24, 0, 1 }, { 0, 49, 1 } } }, - { { { 24, 0, 2 }, { 0, 49, 0 } } }, - { { { 25, 0, 1 }, { 0, 50, 1 } } }, - { { { 25, 0, 0 }, { 0, 50, 0 } } }, - { { { 25, 0, 1 }, { 0, 51, 1 } } }, - { { { 25, 0, 2 }, { 0, 51, 0 } } }, - { { { 26, 0, 1 }, { 0, 52, 1 } } }, - { { { 26, 0, 0 }, { 0, 52, 0 } } }, - { { { 26, 0, 1 }, { 0, 53, 1 } } }, - { { { 26, 0, 2 }, { 0, 53, 0 } } }, - { { { 27, 0, 1 }, { 0, 54, 1 } } }, - { { { 27, 0, 0 }, { 0, 54, 0 } } }, - { { { 27, 0, 1 }, { 0, 55, 1 } } }, - { { { 27, 0, 2 }, { 0, 55, 0 } } }, - { { { 28, 0, 1 }, { 0, 56, 1 } } }, - { { { 28, 0, 0 }, { 0, 56, 0 } } }, - { { { 28, 0, 1 }, { 0, 57, 1 } } }, - { { { 28, 0, 2 }, { 0, 57, 0 } } }, - { { { 29, 0, 1 }, { 0, 58, 1 } } }, - { { { 29, 0, 0 }, { 0, 58, 0 } } }, - { { { 29, 0, 1 }, { 0, 59, 1 } } }, - { { { 29, 0, 2 }, { 0, 59, 0 } } }, - { { { 30, 0, 1 }, { 0, 60, 1 } } }, - { { { 30, 0, 0 }, { 0, 60, 0 } } }, - { { { 30, 0, 1 }, { 0, 61, 1 } } }, - { { { 30, 0, 2 }, { 0, 61, 0 } } }, - { { { 31, 0, 1 }, { 0, 62, 1 } } }, - { { { 31, 0, 0 }, { 0, 62, 0 } } }, - { { { 31, 0, 1 }, { 0, 63, 1 } } }, - { { { 31, 0, 2 }, { 0, 63, 0 } } }, - { { { 32, 0, 2 }, { 1, 63, 1 } } }, - { { { 32, 0, 1 }, { 1, 63, 0 } } }, - { { { 32, 0, 0 }, { 16, 48, 0 } } }, - { { { 32, 0, 1 }, { 2, 63, 0 } } }, - { { { 32, 0, 2 }, { 16, 49, 0 } } }, - { { { 33, 0, 1 }, { 3, 63, 0 } } }, - { { { 33, 0, 0 }, { 16, 50, 0 } } }, - { { { 33, 0, 1 }, { 4, 63, 0 } } }, - { { { 33, 0, 2 }, { 16, 51, 0 } } }, - { { { 34, 0, 1 }, { 5, 63, 0 } } }, - { { { 34, 0, 0 }, { 16, 52, 0 } } }, - { { { 34, 0, 1 }, { 6, 63, 0 } } }, - { { { 34, 0, 2 }, { 16, 53, 0 } } }, - { { { 35, 0, 1 }, { 7, 63, 0 } } }, - { { { 35, 0, 0 }, { 16, 54, 0 } } }, - { { { 35, 0, 1 }, { 8, 63, 0 } } }, - { { { 35, 0, 2 }, { 16, 55, 0 } } }, - { { { 36, 0, 1 }, { 9, 63, 0 } } }, - { { { 36, 0, 0 }, { 16, 56, 0 } } }, - { { { 36, 0, 1 }, { 10, 63, 0 } } }, - { { { 36, 0, 2 }, { 16, 57, 0 } } }, - { { { 37, 0, 1 }, { 11, 63, 0 } } }, - { { { 37, 0, 0 }, { 16, 58, 0 } } }, - { { { 37, 0, 1 }, { 12, 63, 0 } } }, - { { { 37, 0, 2 }, { 16, 59, 0 } } }, - { { { 38, 0, 1 }, { 13, 63, 0 } } }, - { { { 38, 0, 0 }, { 16, 60, 0 } } }, - { { { 38, 0, 1 }, { 14, 63, 0 } } }, - { { { 38, 0, 2 }, { 16, 61, 0 } } }, - { { { 39, 0, 1 }, { 15, 63, 0 } } }, - { { { 39, 0, 0 }, { 16, 62, 0 } } }, - { { { 39, 0, 1 }, { 16, 63, 1 } } }, - { { { 39, 0, 2 }, { 16, 63, 0 } } }, - { { { 40, 0, 1 }, { 17, 63, 1 } } }, - { { { 40, 0, 0 }, { 17, 63, 0 } } }, - { { { 40, 0, 1 }, { 18, 63, 1 } } }, - { { { 40, 0, 2 }, { 18, 63, 0 } } }, - { { { 41, 0, 1 }, { 19, 63, 1 } } }, - { { { 41, 0, 0 }, { 19, 63, 0 } } }, - { { { 41, 0, 1 }, { 20, 63, 1 } } }, - { { { 41, 0, 2 }, { 20, 63, 0 } } }, - { { { 42, 0, 1 }, { 21, 63, 1 } } }, - { { { 42, 0, 0 }, { 21, 63, 0 } } }, - { { { 42, 0, 1 }, { 22, 63, 1 } } }, - { { { 42, 0, 2 }, { 22, 63, 0 } } }, - { { { 43, 0, 1 }, { 23, 63, 1 } } }, - { { { 43, 0, 0 }, { 23, 63, 0 } } }, - { { { 43, 0, 1 }, { 24, 63, 1 } } }, - { { { 43, 0, 2 }, { 24, 63, 0 } } }, - { { { 44, 0, 1 }, { 25, 63, 1 } } }, - { { { 44, 0, 0 }, { 25, 63, 0 } } }, - { { { 44, 0, 1 }, { 26, 63, 1 } } }, - { { { 44, 0, 2 }, { 26, 63, 0 } } }, - { { { 45, 0, 1 }, { 27, 63, 1 } } }, - { { { 45, 0, 0 }, { 27, 63, 0 } } }, - { { { 45, 0, 1 }, { 28, 63, 1 } } }, - { { { 45, 0, 2 }, { 28, 63, 0 } } }, - { { { 46, 0, 1 }, { 29, 63, 1 } } }, - { { { 46, 0, 0 }, { 29, 63, 0 } } }, - { { { 46, 0, 1 }, { 30, 63, 1 } } }, - { { { 46, 0, 2 }, { 30, 63, 0 } } }, - { { { 47, 0, 1 }, { 31, 63, 1 } } }, - { { { 47, 0, 0 }, { 31, 63, 0 } } }, - { { { 47, 0, 1 }, { 32, 63, 1 } } }, - { { { 47, 0, 2 }, { 32, 63, 0 } } }, - { { { 48, 0, 2 }, { 33, 63, 1 } } }, - { { { 48, 0, 1 }, { 33, 63, 0 } } }, - { { { 48, 0, 0 }, { 48, 48, 0 } } }, - { { { 48, 0, 1 }, { 34, 63, 0 } } }, - { { { 48, 0, 2 }, { 48, 49, 0 } } }, - { { { 49, 0, 1 }, { 35, 63, 0 } } }, - { { { 49, 0, 0 }, { 48, 50, 0 } } }, - { { { 49, 0, 1 }, { 36, 63, 0 } } }, - { { { 49, 0, 2 }, { 48, 51, 0 } } }, - { { { 50, 0, 1 }, { 37, 63, 0 } } }, - { { { 50, 0, 0 }, { 48, 52, 0 } } }, - { { { 50, 0, 1 }, { 38, 63, 0 } } }, - { { { 50, 0, 2 }, { 48, 53, 0 } } }, - { { { 51, 0, 1 }, { 39, 63, 0 } } }, - { { { 51, 0, 0 }, { 48, 54, 0 } } }, - { { { 51, 0, 1 }, { 40, 63, 0 } } }, - { { { 51, 0, 2 }, { 48, 55, 0 } } }, - { { { 52, 0, 1 }, { 41, 63, 0 } } }, - { { { 52, 0, 0 }, { 48, 56, 0 } } }, - { { { 52, 0, 1 }, { 42, 63, 0 } } }, - { { { 52, 0, 2 }, { 48, 57, 0 } } }, - { { { 53, 0, 1 }, { 43, 63, 0 } } }, - { { { 53, 0, 0 }, { 48, 58, 0 } } }, - { { { 53, 0, 1 }, { 44, 63, 0 } } }, - { { { 53, 0, 2 }, { 48, 59, 0 } } }, - { { { 54, 0, 1 }, { 45, 63, 0 } } }, - { { { 54, 0, 0 }, { 48, 60, 0 } } }, - { { { 54, 0, 1 }, { 46, 63, 0 } } }, - { { { 54, 0, 2 }, { 48, 61, 0 } } }, - { { { 55, 0, 1 }, { 47, 63, 0 } } }, - { { { 55, 0, 0 }, { 48, 62, 0 } } }, - { { { 55, 0, 1 }, { 48, 63, 1 } } }, - { { { 55, 0, 2 }, { 48, 63, 0 } } }, - { { { 56, 0, 1 }, { 49, 63, 1 } } }, - { { { 56, 0, 0 }, { 49, 63, 0 } } }, - { { { 56, 0, 1 }, { 50, 63, 1 } } }, - { { { 56, 0, 2 }, { 50, 63, 0 } } }, - { { { 57, 0, 1 }, { 51, 63, 1 } } }, - { { { 57, 0, 0 }, { 51, 63, 0 } } }, - { { { 57, 0, 1 }, { 52, 63, 1 } } }, - { { { 57, 0, 2 }, { 52, 63, 0 } } }, - { { { 58, 0, 1 }, { 53, 63, 1 } } }, - { { { 58, 0, 0 }, { 53, 63, 0 } } }, - { { { 58, 0, 1 }, { 54, 63, 1 } } }, - { { { 58, 0, 2 }, { 54, 63, 0 } } }, - { { { 59, 0, 1 }, { 55, 63, 1 } } }, - { { { 59, 0, 0 }, { 55, 63, 0 } } }, - { { { 59, 0, 1 }, { 56, 63, 1 } } }, - { { { 59, 0, 2 }, { 56, 63, 0 } } }, - { { { 60, 0, 1 }, { 57, 63, 1 } } }, - { { { 60, 0, 0 }, { 57, 63, 0 } } }, - { { { 60, 0, 1 }, { 58, 63, 1 } } }, - { { { 60, 0, 2 }, { 58, 63, 0 } } }, - { { { 61, 0, 1 }, { 59, 63, 1 } } }, - { { { 61, 0, 0 }, { 59, 63, 0 } } }, - { { { 61, 0, 1 }, { 60, 63, 1 } } }, - { { { 61, 0, 2 }, { 60, 63, 0 } } }, - { { { 62, 0, 1 }, { 61, 63, 1 } } }, - { { { 62, 0, 0 }, { 61, 63, 0 } } }, - { { { 62, 0, 1 }, { 62, 63, 1 } } }, - { { { 62, 0, 2 }, { 62, 63, 0 } } }, - { { { 63, 0, 1 }, { 63, 63, 1 } } }, - { { { 63, 0, 0 }, { 63, 63, 0 } } } -}; - -static SingleColourLookup const lookup_5_4[] = -{ - { { { 0, 0, 0 }, { 0, 0, 0 } } }, - { { { 0, 0, 1 }, { 0, 1, 1 } } }, - { { { 0, 0, 2 }, { 0, 1, 0 } } }, - { { { 0, 0, 3 }, { 0, 1, 1 } } }, - { { { 0, 0, 4 }, { 0, 2, 1 } } }, - { { { 1, 0, 3 }, { 0, 2, 0 } } }, - { { { 1, 0, 2 }, { 0, 2, 1 } } }, - { { { 1, 0, 1 }, { 0, 3, 1 } } }, - { { { 1, 0, 0 }, { 0, 3, 0 } } }, - { { { 1, 0, 1 }, { 1, 2, 1 } } }, - { { { 1, 0, 2 }, { 1, 2, 0 } } }, - { { { 1, 0, 3 }, { 0, 4, 0 } } }, - { { { 1, 0, 4 }, { 0, 5, 1 } } }, - { { { 2, 0, 3 }, { 0, 5, 0 } } }, - { { { 2, 0, 2 }, { 0, 5, 1 } } }, - { { { 2, 0, 1 }, { 0, 6, 1 } } }, - { { { 2, 0, 0 }, { 0, 6, 0 } } }, - { { { 2, 0, 1 }, { 2, 3, 1 } } }, - { { { 2, 0, 2 }, { 2, 3, 0 } } }, - { { { 2, 0, 3 }, { 0, 7, 0 } } }, - { { { 2, 0, 4 }, { 1, 6, 1 } } }, - { { { 3, 0, 3 }, { 1, 6, 0 } } }, - { { { 3, 0, 2 }, { 0, 8, 0 } } }, - { { { 3, 0, 1 }, { 0, 9, 1 } } }, - { { { 3, 0, 0 }, { 0, 9, 0 } } }, - { { { 3, 0, 1 }, { 0, 9, 1 } } }, - { { { 3, 0, 2 }, { 0, 10, 1 } } }, - { { { 3, 0, 3 }, { 0, 10, 0 } } }, - { { { 3, 0, 4 }, { 2, 7, 1 } } }, - { { { 4, 0, 4 }, { 2, 7, 0 } } }, - { { { 4, 0, 3 }, { 0, 11, 0 } } }, - { { { 4, 0, 2 }, { 1, 10, 1 } } }, - { { { 4, 0, 1 }, { 1, 10, 0 } } }, - { { { 4, 0, 0 }, { 0, 12, 0 } } }, - { { { 4, 0, 1 }, { 0, 13, 1 } } }, - { { { 4, 0, 2 }, { 0, 13, 0 } } }, - { { { 4, 0, 3 }, { 0, 13, 1 } } }, - { { { 4, 0, 4 }, { 0, 14, 1 } } }, - { { { 5, 0, 3 }, { 0, 14, 0 } } }, - { { { 5, 0, 2 }, { 2, 11, 1 } } }, - { { { 5, 0, 1 }, { 2, 11, 0 } } }, - { { { 5, 0, 0 }, { 0, 15, 0 } } }, - { { { 5, 0, 1 }, { 1, 14, 1 } } }, - { { { 5, 0, 2 }, { 1, 14, 0 } } }, - { { { 5, 0, 3 }, { 0, 16, 0 } } }, - { { { 5, 0, 4 }, { 0, 17, 1 } } }, - { { { 6, 0, 3 }, { 0, 17, 0 } } }, - { { { 6, 0, 2 }, { 0, 17, 1 } } }, - { { { 6, 0, 1 }, { 0, 18, 1 } } }, - { { { 6, 0, 0 }, { 0, 18, 0 } } }, - { { { 6, 0, 1 }, { 2, 15, 1 } } }, - { { { 6, 0, 2 }, { 2, 15, 0 } } }, - { { { 6, 0, 3 }, { 0, 19, 0 } } }, - { { { 6, 0, 4 }, { 1, 18, 1 } } }, - { { { 7, 0, 3 }, { 1, 18, 0 } } }, - { { { 7, 0, 2 }, { 0, 20, 0 } } }, - { { { 7, 0, 1 }, { 0, 21, 1 } } }, - { { { 7, 0, 0 }, { 0, 21, 0 } } }, - { { { 7, 0, 1 }, { 0, 21, 1 } } }, - { { { 7, 0, 2 }, { 0, 22, 1 } } }, - { { { 7, 0, 3 }, { 0, 22, 0 } } }, - { { { 7, 0, 4 }, { 2, 19, 1 } } }, - { { { 8, 0, 4 }, { 2, 19, 0 } } }, - { { { 8, 0, 3 }, { 0, 23, 0 } } }, - { { { 8, 0, 2 }, { 1, 22, 1 } } }, - { { { 8, 0, 1 }, { 1, 22, 0 } } }, - { { { 8, 0, 0 }, { 0, 24, 0 } } }, - { { { 8, 0, 1 }, { 0, 25, 1 } } }, - { { { 8, 0, 2 }, { 0, 25, 0 } } }, - { { { 8, 0, 3 }, { 0, 25, 1 } } }, - { { { 8, 0, 4 }, { 0, 26, 1 } } }, - { { { 9, 0, 3 }, { 0, 26, 0 } } }, - { { { 9, 0, 2 }, { 2, 23, 1 } } }, - { { { 9, 0, 1 }, { 2, 23, 0 } } }, - { { { 9, 0, 0 }, { 0, 27, 0 } } }, - { { { 9, 0, 1 }, { 1, 26, 1 } } }, - { { { 9, 0, 2 }, { 1, 26, 0 } } }, - { { { 9, 0, 3 }, { 0, 28, 0 } } }, - { { { 9, 0, 4 }, { 0, 29, 1 } } }, - { { { 10, 0, 3 }, { 0, 29, 0 } } }, - { { { 10, 0, 2 }, { 0, 29, 1 } } }, - { { { 10, 0, 1 }, { 0, 30, 1 } } }, - { { { 10, 0, 0 }, { 0, 30, 0 } } }, - { { { 10, 0, 1 }, { 2, 27, 1 } } }, - { { { 10, 0, 2 }, { 2, 27, 0 } } }, - { { { 10, 0, 3 }, { 0, 31, 0 } } }, - { { { 10, 0, 4 }, { 1, 30, 1 } } }, - { { { 11, 0, 3 }, { 1, 30, 0 } } }, - { { { 11, 0, 2 }, { 4, 24, 0 } } }, - { { { 11, 0, 1 }, { 1, 31, 1 } } }, - { { { 11, 0, 0 }, { 1, 31, 0 } } }, - { { { 11, 0, 1 }, { 1, 31, 1 } } }, - { { { 11, 0, 2 }, { 2, 30, 1 } } }, - { { { 11, 0, 3 }, { 2, 30, 0 } } }, - { { { 11, 0, 4 }, { 2, 31, 1 } } }, - { { { 12, 0, 4 }, { 2, 31, 0 } } }, - { { { 12, 0, 3 }, { 4, 27, 0 } } }, - { { { 12, 0, 2 }, { 3, 30, 1 } } }, - { { { 12, 0, 1 }, { 3, 30, 0 } } }, - { { { 12, 0, 0 }, { 4, 28, 0 } } }, - { { { 12, 0, 1 }, { 3, 31, 1 } } }, - { { { 12, 0, 2 }, { 3, 31, 0 } } }, - { { { 12, 0, 3 }, { 3, 31, 1 } } }, - { { { 12, 0, 4 }, { 4, 30, 1 } } }, - { { { 13, 0, 3 }, { 4, 30, 0 } } }, - { { { 13, 0, 2 }, { 6, 27, 1 } } }, - { { { 13, 0, 1 }, { 6, 27, 0 } } }, - { { { 13, 0, 0 }, { 4, 31, 0 } } }, - { { { 13, 0, 1 }, { 5, 30, 1 } } }, - { { { 13, 0, 2 }, { 5, 30, 0 } } }, - { { { 13, 0, 3 }, { 8, 24, 0 } } }, - { { { 13, 0, 4 }, { 5, 31, 1 } } }, - { { { 14, 0, 3 }, { 5, 31, 0 } } }, - { { { 14, 0, 2 }, { 5, 31, 1 } } }, - { { { 14, 0, 1 }, { 6, 30, 1 } } }, - { { { 14, 0, 0 }, { 6, 30, 0 } } }, - { { { 14, 0, 1 }, { 6, 31, 1 } } }, - { { { 14, 0, 2 }, { 6, 31, 0 } } }, - { { { 14, 0, 3 }, { 8, 27, 0 } } }, - { { { 14, 0, 4 }, { 7, 30, 1 } } }, - { { { 15, 0, 3 }, { 7, 30, 0 } } }, - { { { 15, 0, 2 }, { 8, 28, 0 } } }, - { { { 15, 0, 1 }, { 7, 31, 1 } } }, - { { { 15, 0, 0 }, { 7, 31, 0 } } }, - { { { 15, 0, 1 }, { 7, 31, 1 } } }, - { { { 15, 0, 2 }, { 8, 30, 1 } } }, - { { { 15, 0, 3 }, { 8, 30, 0 } } }, - { { { 15, 0, 4 }, { 10, 27, 1 } } }, - { { { 16, 0, 4 }, { 10, 27, 0 } } }, - { { { 16, 0, 3 }, { 8, 31, 0 } } }, - { { { 16, 0, 2 }, { 9, 30, 1 } } }, - { { { 16, 0, 1 }, { 9, 30, 0 } } }, - { { { 16, 0, 0 }, { 12, 24, 0 } } }, - { { { 16, 0, 1 }, { 9, 31, 1 } } }, - { { { 16, 0, 2 }, { 9, 31, 0 } } }, - { { { 16, 0, 3 }, { 9, 31, 1 } } }, - { { { 16, 0, 4 }, { 10, 30, 1 } } }, - { { { 17, 0, 3 }, { 10, 30, 0 } } }, - { { { 17, 0, 2 }, { 10, 31, 1 } } }, - { { { 17, 0, 1 }, { 10, 31, 0 } } }, - { { { 17, 0, 0 }, { 12, 27, 0 } } }, - { { { 17, 0, 1 }, { 11, 30, 1 } } }, - { { { 17, 0, 2 }, { 11, 30, 0 } } }, - { { { 17, 0, 3 }, { 12, 28, 0 } } }, - { { { 17, 0, 4 }, { 11, 31, 1 } } }, - { { { 18, 0, 3 }, { 11, 31, 0 } } }, - { { { 18, 0, 2 }, { 11, 31, 1 } } }, - { { { 18, 0, 1 }, { 12, 30, 1 } } }, - { { { 18, 0, 0 }, { 12, 30, 0 } } }, - { { { 18, 0, 1 }, { 14, 27, 1 } } }, - { { { 18, 0, 2 }, { 14, 27, 0 } } }, - { { { 18, 0, 3 }, { 12, 31, 0 } } }, - { { { 18, 0, 4 }, { 13, 30, 1 } } }, - { { { 19, 0, 3 }, { 13, 30, 0 } } }, - { { { 19, 0, 2 }, { 16, 24, 0 } } }, - { { { 19, 0, 1 }, { 13, 31, 1 } } }, - { { { 19, 0, 0 }, { 13, 31, 0 } } }, - { { { 19, 0, 1 }, { 13, 31, 1 } } }, - { { { 19, 0, 2 }, { 14, 30, 1 } } }, - { { { 19, 0, 3 }, { 14, 30, 0 } } }, - { { { 19, 0, 4 }, { 14, 31, 1 } } }, - { { { 20, 0, 4 }, { 14, 31, 0 } } }, - { { { 20, 0, 3 }, { 16, 27, 0 } } }, - { { { 20, 0, 2 }, { 15, 30, 1 } } }, - { { { 20, 0, 1 }, { 15, 30, 0 } } }, - { { { 20, 0, 0 }, { 16, 28, 0 } } }, - { { { 20, 0, 1 }, { 15, 31, 1 } } }, - { { { 20, 0, 2 }, { 15, 31, 0 } } }, - { { { 20, 0, 3 }, { 15, 31, 1 } } }, - { { { 20, 0, 4 }, { 16, 30, 1 } } }, - { { { 21, 0, 3 }, { 16, 30, 0 } } }, - { { { 21, 0, 2 }, { 18, 27, 1 } } }, - { { { 21, 0, 1 }, { 18, 27, 0 } } }, - { { { 21, 0, 0 }, { 16, 31, 0 } } }, - { { { 21, 0, 1 }, { 17, 30, 1 } } }, - { { { 21, 0, 2 }, { 17, 30, 0 } } }, - { { { 21, 0, 3 }, { 20, 24, 0 } } }, - { { { 21, 0, 4 }, { 17, 31, 1 } } }, - { { { 22, 0, 3 }, { 17, 31, 0 } } }, - { { { 22, 0, 2 }, { 17, 31, 1 } } }, - { { { 22, 0, 1 }, { 18, 30, 1 } } }, - { { { 22, 0, 0 }, { 18, 30, 0 } } }, - { { { 22, 0, 1 }, { 18, 31, 1 } } }, - { { { 22, 0, 2 }, { 18, 31, 0 } } }, - { { { 22, 0, 3 }, { 20, 27, 0 } } }, - { { { 22, 0, 4 }, { 19, 30, 1 } } }, - { { { 23, 0, 3 }, { 19, 30, 0 } } }, - { { { 23, 0, 2 }, { 20, 28, 0 } } }, - { { { 23, 0, 1 }, { 19, 31, 1 } } }, - { { { 23, 0, 0 }, { 19, 31, 0 } } }, - { { { 23, 0, 1 }, { 19, 31, 1 } } }, - { { { 23, 0, 2 }, { 20, 30, 1 } } }, - { { { 23, 0, 3 }, { 20, 30, 0 } } }, - { { { 23, 0, 4 }, { 22, 27, 1 } } }, - { { { 24, 0, 4 }, { 22, 27, 0 } } }, - { { { 24, 0, 3 }, { 20, 31, 0 } } }, - { { { 24, 0, 2 }, { 21, 30, 1 } } }, - { { { 24, 0, 1 }, { 21, 30, 0 } } }, - { { { 24, 0, 0 }, { 24, 24, 0 } } }, - { { { 24, 0, 1 }, { 21, 31, 1 } } }, - { { { 24, 0, 2 }, { 21, 31, 0 } } }, - { { { 24, 0, 3 }, { 21, 31, 1 } } }, - { { { 24, 0, 4 }, { 22, 30, 1 } } }, - { { { 25, 0, 3 }, { 22, 30, 0 } } }, - { { { 25, 0, 2 }, { 22, 31, 1 } } }, - { { { 25, 0, 1 }, { 22, 31, 0 } } }, - { { { 25, 0, 0 }, { 24, 27, 0 } } }, - { { { 25, 0, 1 }, { 23, 30, 1 } } }, - { { { 25, 0, 2 }, { 23, 30, 0 } } }, - { { { 25, 0, 3 }, { 24, 28, 0 } } }, - { { { 25, 0, 4 }, { 23, 31, 1 } } }, - { { { 26, 0, 3 }, { 23, 31, 0 } } }, - { { { 26, 0, 2 }, { 23, 31, 1 } } }, - { { { 26, 0, 1 }, { 24, 30, 1 } } }, - { { { 26, 0, 0 }, { 24, 30, 0 } } }, - { { { 26, 0, 1 }, { 26, 27, 1 } } }, - { { { 26, 0, 2 }, { 26, 27, 0 } } }, - { { { 26, 0, 3 }, { 24, 31, 0 } } }, - { { { 26, 0, 4 }, { 25, 30, 1 } } }, - { { { 27, 0, 3 }, { 25, 30, 0 } } }, - { { { 27, 0, 2 }, { 28, 24, 0 } } }, - { { { 27, 0, 1 }, { 25, 31, 1 } } }, - { { { 27, 0, 0 }, { 25, 31, 0 } } }, - { { { 27, 0, 1 }, { 25, 31, 1 } } }, - { { { 27, 0, 2 }, { 26, 30, 1 } } }, - { { { 27, 0, 3 }, { 26, 30, 0 } } }, - { { { 27, 0, 4 }, { 26, 31, 1 } } }, - { { { 28, 0, 4 }, { 26, 31, 0 } } }, - { { { 28, 0, 3 }, { 28, 27, 0 } } }, - { { { 28, 0, 2 }, { 27, 30, 1 } } }, - { { { 28, 0, 1 }, { 27, 30, 0 } } }, - { { { 28, 0, 0 }, { 28, 28, 0 } } }, - { { { 28, 0, 1 }, { 27, 31, 1 } } }, - { { { 28, 0, 2 }, { 27, 31, 0 } } }, - { { { 28, 0, 3 }, { 27, 31, 1 } } }, - { { { 28, 0, 4 }, { 28, 30, 1 } } }, - { { { 29, 0, 3 }, { 28, 30, 0 } } }, - { { { 29, 0, 2 }, { 30, 27, 1 } } }, - { { { 29, 0, 1 }, { 30, 27, 0 } } }, - { { { 29, 0, 0 }, { 28, 31, 0 } } }, - { { { 29, 0, 1 }, { 29, 30, 1 } } }, - { { { 29, 0, 2 }, { 29, 30, 0 } } }, - { { { 29, 0, 3 }, { 29, 30, 1 } } }, - { { { 29, 0, 4 }, { 29, 31, 1 } } }, - { { { 30, 0, 3 }, { 29, 31, 0 } } }, - { { { 30, 0, 2 }, { 29, 31, 1 } } }, - { { { 30, 0, 1 }, { 30, 30, 1 } } }, - { { { 30, 0, 0 }, { 30, 30, 0 } } }, - { { { 30, 0, 1 }, { 30, 31, 1 } } }, - { { { 30, 0, 2 }, { 30, 31, 0 } } }, - { { { 30, 0, 3 }, { 30, 31, 1 } } }, - { { { 30, 0, 4 }, { 31, 30, 1 } } }, - { { { 31, 0, 3 }, { 31, 30, 0 } } }, - { { { 31, 0, 2 }, { 31, 30, 1 } } }, - { { { 31, 0, 1 }, { 31, 31, 1 } } }, - { { { 31, 0, 0 }, { 31, 31, 0 } } } -}; - -static SingleColourLookup const lookup_6_4[] = -{ - { { { 0, 0, 0 }, { 0, 0, 0 } } }, - { { { 0, 0, 1 }, { 0, 1, 0 } } }, - { { { 0, 0, 2 }, { 0, 2, 0 } } }, - { { { 1, 0, 1 }, { 0, 3, 1 } } }, - { { { 1, 0, 0 }, { 0, 3, 0 } } }, - { { { 1, 0, 1 }, { 0, 4, 0 } } }, - { { { 1, 0, 2 }, { 0, 5, 0 } } }, - { { { 2, 0, 1 }, { 0, 6, 1 } } }, - { { { 2, 0, 0 }, { 0, 6, 0 } } }, - { { { 2, 0, 1 }, { 0, 7, 0 } } }, - { { { 2, 0, 2 }, { 0, 8, 0 } } }, - { { { 3, 0, 1 }, { 0, 9, 1 } } }, - { { { 3, 0, 0 }, { 0, 9, 0 } } }, - { { { 3, 0, 1 }, { 0, 10, 0 } } }, - { { { 3, 0, 2 }, { 0, 11, 0 } } }, - { { { 4, 0, 1 }, { 0, 12, 1 } } }, - { { { 4, 0, 0 }, { 0, 12, 0 } } }, - { { { 4, 0, 1 }, { 0, 13, 0 } } }, - { { { 4, 0, 2 }, { 0, 14, 0 } } }, - { { { 5, 0, 1 }, { 0, 15, 1 } } }, - { { { 5, 0, 0 }, { 0, 15, 0 } } }, - { { { 5, 0, 1 }, { 0, 16, 0 } } }, - { { { 5, 0, 2 }, { 1, 15, 0 } } }, - { { { 6, 0, 1 }, { 0, 17, 0 } } }, - { { { 6, 0, 0 }, { 0, 18, 0 } } }, - { { { 6, 0, 1 }, { 0, 19, 0 } } }, - { { { 6, 0, 2 }, { 3, 14, 0 } } }, - { { { 7, 0, 1 }, { 0, 20, 0 } } }, - { { { 7, 0, 0 }, { 0, 21, 0 } } }, - { { { 7, 0, 1 }, { 0, 22, 0 } } }, - { { { 7, 0, 2 }, { 4, 15, 0 } } }, - { { { 8, 0, 1 }, { 0, 23, 0 } } }, - { { { 8, 0, 0 }, { 0, 24, 0 } } }, - { { { 8, 0, 1 }, { 0, 25, 0 } } }, - { { { 8, 0, 2 }, { 6, 14, 0 } } }, - { { { 9, 0, 1 }, { 0, 26, 0 } } }, - { { { 9, 0, 0 }, { 0, 27, 0 } } }, - { { { 9, 0, 1 }, { 0, 28, 0 } } }, - { { { 9, 0, 2 }, { 7, 15, 0 } } }, - { { { 10, 0, 1 }, { 0, 29, 0 } } }, - { { { 10, 0, 0 }, { 0, 30, 0 } } }, - { { { 10, 0, 1 }, { 0, 31, 0 } } }, - { { { 10, 0, 2 }, { 9, 14, 0 } } }, - { { { 11, 0, 1 }, { 0, 32, 0 } } }, - { { { 11, 0, 0 }, { 0, 33, 0 } } }, - { { { 11, 0, 1 }, { 2, 30, 0 } } }, - { { { 11, 0, 2 }, { 0, 34, 0 } } }, - { { { 12, 0, 1 }, { 0, 35, 0 } } }, - { { { 12, 0, 0 }, { 0, 36, 0 } } }, - { { { 12, 0, 1 }, { 3, 31, 0 } } }, - { { { 12, 0, 2 }, { 0, 37, 0 } } }, - { { { 13, 0, 1 }, { 0, 38, 0 } } }, - { { { 13, 0, 0 }, { 0, 39, 0 } } }, - { { { 13, 0, 1 }, { 5, 30, 0 } } }, - { { { 13, 0, 2 }, { 0, 40, 0 } } }, - { { { 14, 0, 1 }, { 0, 41, 0 } } }, - { { { 14, 0, 0 }, { 0, 42, 0 } } }, - { { { 14, 0, 1 }, { 6, 31, 0 } } }, - { { { 14, 0, 2 }, { 0, 43, 0 } } }, - { { { 15, 0, 1 }, { 0, 44, 0 } } }, - { { { 15, 0, 0 }, { 0, 45, 0 } } }, - { { { 15, 0, 1 }, { 8, 30, 0 } } }, - { { { 15, 0, 2 }, { 0, 46, 0 } } }, - { { { 16, 0, 2 }, { 0, 47, 0 } } }, - { { { 16, 0, 1 }, { 1, 46, 0 } } }, - { { { 16, 0, 0 }, { 0, 48, 0 } } }, - { { { 16, 0, 1 }, { 0, 49, 0 } } }, - { { { 16, 0, 2 }, { 0, 50, 0 } } }, - { { { 17, 0, 1 }, { 2, 47, 0 } } }, - { { { 17, 0, 0 }, { 0, 51, 0 } } }, - { { { 17, 0, 1 }, { 0, 52, 0 } } }, - { { { 17, 0, 2 }, { 0, 53, 0 } } }, - { { { 18, 0, 1 }, { 4, 46, 0 } } }, - { { { 18, 0, 0 }, { 0, 54, 0 } } }, - { { { 18, 0, 1 }, { 0, 55, 0 } } }, - { { { 18, 0, 2 }, { 0, 56, 0 } } }, - { { { 19, 0, 1 }, { 5, 47, 0 } } }, - { { { 19, 0, 0 }, { 0, 57, 0 } } }, - { { { 19, 0, 1 }, { 0, 58, 0 } } }, - { { { 19, 0, 2 }, { 0, 59, 0 } } }, - { { { 20, 0, 1 }, { 7, 46, 0 } } }, - { { { 20, 0, 0 }, { 0, 60, 0 } } }, - { { { 20, 0, 1 }, { 0, 61, 0 } } }, - { { { 20, 0, 2 }, { 0, 62, 0 } } }, - { { { 21, 0, 1 }, { 8, 47, 0 } } }, - { { { 21, 0, 0 }, { 0, 63, 0 } } }, - { { { 21, 0, 1 }, { 1, 62, 0 } } }, - { { { 21, 0, 2 }, { 1, 63, 0 } } }, - { { { 22, 0, 1 }, { 10, 46, 0 } } }, - { { { 22, 0, 0 }, { 2, 62, 0 } } }, - { { { 22, 0, 1 }, { 2, 63, 0 } } }, - { { { 22, 0, 2 }, { 3, 62, 0 } } }, - { { { 23, 0, 1 }, { 11, 47, 0 } } }, - { { { 23, 0, 0 }, { 3, 63, 0 } } }, - { { { 23, 0, 1 }, { 4, 62, 0 } } }, - { { { 23, 0, 2 }, { 4, 63, 0 } } }, - { { { 24, 0, 1 }, { 13, 46, 0 } } }, - { { { 24, 0, 0 }, { 5, 62, 0 } } }, - { { { 24, 0, 1 }, { 5, 63, 0 } } }, - { { { 24, 0, 2 }, { 6, 62, 0 } } }, - { { { 25, 0, 1 }, { 14, 47, 0 } } }, - { { { 25, 0, 0 }, { 6, 63, 0 } } }, - { { { 25, 0, 1 }, { 7, 62, 0 } } }, - { { { 25, 0, 2 }, { 7, 63, 0 } } }, - { { { 26, 0, 1 }, { 16, 45, 0 } } }, - { { { 26, 0, 0 }, { 8, 62, 0 } } }, - { { { 26, 0, 1 }, { 8, 63, 0 } } }, - { { { 26, 0, 2 }, { 9, 62, 0 } } }, - { { { 27, 0, 1 }, { 16, 48, 0 } } }, - { { { 27, 0, 0 }, { 9, 63, 0 } } }, - { { { 27, 0, 1 }, { 10, 62, 0 } } }, - { { { 27, 0, 2 }, { 10, 63, 0 } } }, - { { { 28, 0, 1 }, { 16, 51, 0 } } }, - { { { 28, 0, 0 }, { 11, 62, 0 } } }, - { { { 28, 0, 1 }, { 11, 63, 0 } } }, - { { { 28, 0, 2 }, { 12, 62, 0 } } }, - { { { 29, 0, 1 }, { 16, 54, 0 } } }, - { { { 29, 0, 0 }, { 12, 63, 0 } } }, - { { { 29, 0, 1 }, { 13, 62, 0 } } }, - { { { 29, 0, 2 }, { 13, 63, 0 } } }, - { { { 30, 0, 1 }, { 16, 57, 0 } } }, - { { { 30, 0, 0 }, { 14, 62, 0 } } }, - { { { 30, 0, 1 }, { 14, 63, 0 } } }, - { { { 30, 0, 2 }, { 15, 62, 0 } } }, - { { { 31, 0, 1 }, { 16, 60, 0 } } }, - { { { 31, 0, 0 }, { 15, 63, 0 } } }, - { { { 31, 0, 1 }, { 24, 46, 0 } } }, - { { { 31, 0, 2 }, { 16, 62, 0 } } }, - { { { 32, 0, 2 }, { 16, 63, 0 } } }, - { { { 32, 0, 1 }, { 17, 62, 0 } } }, - { { { 32, 0, 0 }, { 25, 47, 0 } } }, - { { { 32, 0, 1 }, { 17, 63, 0 } } }, - { { { 32, 0, 2 }, { 18, 62, 0 } } }, - { { { 33, 0, 1 }, { 18, 63, 0 } } }, - { { { 33, 0, 0 }, { 27, 46, 0 } } }, - { { { 33, 0, 1 }, { 19, 62, 0 } } }, - { { { 33, 0, 2 }, { 19, 63, 0 } } }, - { { { 34, 0, 1 }, { 20, 62, 0 } } }, - { { { 34, 0, 0 }, { 28, 47, 0 } } }, - { { { 34, 0, 1 }, { 20, 63, 0 } } }, - { { { 34, 0, 2 }, { 21, 62, 0 } } }, - { { { 35, 0, 1 }, { 21, 63, 0 } } }, - { { { 35, 0, 0 }, { 30, 46, 0 } } }, - { { { 35, 0, 1 }, { 22, 62, 0 } } }, - { { { 35, 0, 2 }, { 22, 63, 0 } } }, - { { { 36, 0, 1 }, { 23, 62, 0 } } }, - { { { 36, 0, 0 }, { 31, 47, 0 } } }, - { { { 36, 0, 1 }, { 23, 63, 0 } } }, - { { { 36, 0, 2 }, { 24, 62, 0 } } }, - { { { 37, 0, 1 }, { 24, 63, 0 } } }, - { { { 37, 0, 0 }, { 32, 47, 0 } } }, - { { { 37, 0, 1 }, { 25, 62, 0 } } }, - { { { 37, 0, 2 }, { 25, 63, 0 } } }, - { { { 38, 0, 1 }, { 26, 62, 0 } } }, - { { { 38, 0, 0 }, { 32, 50, 0 } } }, - { { { 38, 0, 1 }, { 26, 63, 0 } } }, - { { { 38, 0, 2 }, { 27, 62, 0 } } }, - { { { 39, 0, 1 }, { 27, 63, 0 } } }, - { { { 39, 0, 0 }, { 32, 53, 0 } } }, - { { { 39, 0, 1 }, { 28, 62, 0 } } }, - { { { 39, 0, 2 }, { 28, 63, 0 } } }, - { { { 40, 0, 1 }, { 29, 62, 0 } } }, - { { { 40, 0, 0 }, { 32, 56, 0 } } }, - { { { 40, 0, 1 }, { 29, 63, 0 } } }, - { { { 40, 0, 2 }, { 30, 62, 0 } } }, - { { { 41, 0, 1 }, { 30, 63, 0 } } }, - { { { 41, 0, 0 }, { 32, 59, 0 } } }, - { { { 41, 0, 1 }, { 31, 62, 0 } } }, - { { { 41, 0, 2 }, { 31, 63, 0 } } }, - { { { 42, 0, 1 }, { 32, 61, 0 } } }, - { { { 42, 0, 0 }, { 32, 62, 0 } } }, - { { { 42, 0, 1 }, { 32, 63, 0 } } }, - { { { 42, 0, 2 }, { 41, 46, 0 } } }, - { { { 43, 0, 1 }, { 33, 62, 0 } } }, - { { { 43, 0, 0 }, { 33, 63, 0 } } }, - { { { 43, 0, 1 }, { 34, 62, 0 } } }, - { { { 43, 0, 2 }, { 42, 47, 0 } } }, - { { { 44, 0, 1 }, { 34, 63, 0 } } }, - { { { 44, 0, 0 }, { 35, 62, 0 } } }, - { { { 44, 0, 1 }, { 35, 63, 0 } } }, - { { { 44, 0, 2 }, { 44, 46, 0 } } }, - { { { 45, 0, 1 }, { 36, 62, 0 } } }, - { { { 45, 0, 0 }, { 36, 63, 0 } } }, - { { { 45, 0, 1 }, { 37, 62, 0 } } }, - { { { 45, 0, 2 }, { 45, 47, 0 } } }, - { { { 46, 0, 1 }, { 37, 63, 0 } } }, - { { { 46, 0, 0 }, { 38, 62, 0 } } }, - { { { 46, 0, 1 }, { 38, 63, 0 } } }, - { { { 46, 0, 2 }, { 47, 46, 0 } } }, - { { { 47, 0, 1 }, { 39, 62, 0 } } }, - { { { 47, 0, 0 }, { 39, 63, 0 } } }, - { { { 47, 0, 1 }, { 40, 62, 0 } } }, - { { { 47, 0, 2 }, { 48, 46, 0 } } }, - { { { 48, 0, 2 }, { 40, 63, 0 } } }, - { { { 48, 0, 1 }, { 41, 62, 0 } } }, - { { { 48, 0, 0 }, { 41, 63, 0 } } }, - { { { 48, 0, 1 }, { 48, 49, 0 } } }, - { { { 48, 0, 2 }, { 42, 62, 0 } } }, - { { { 49, 0, 1 }, { 42, 63, 0 } } }, - { { { 49, 0, 0 }, { 43, 62, 0 } } }, - { { { 49, 0, 1 }, { 48, 52, 0 } } }, - { { { 49, 0, 2 }, { 43, 63, 0 } } }, - { { { 50, 0, 1 }, { 44, 62, 0 } } }, - { { { 50, 0, 0 }, { 44, 63, 0 } } }, - { { { 50, 0, 1 }, { 48, 55, 0 } } }, - { { { 50, 0, 2 }, { 45, 62, 0 } } }, - { { { 51, 0, 1 }, { 45, 63, 0 } } }, - { { { 51, 0, 0 }, { 46, 62, 0 } } }, - { { { 51, 0, 1 }, { 48, 58, 0 } } }, - { { { 51, 0, 2 }, { 46, 63, 0 } } }, - { { { 52, 0, 1 }, { 47, 62, 0 } } }, - { { { 52, 0, 0 }, { 47, 63, 0 } } }, - { { { 52, 0, 1 }, { 48, 61, 0 } } }, - { { { 52, 0, 2 }, { 48, 62, 0 } } }, - { { { 53, 0, 1 }, { 56, 47, 0 } } }, - { { { 53, 0, 0 }, { 48, 63, 0 } } }, - { { { 53, 0, 1 }, { 49, 62, 0 } } }, - { { { 53, 0, 2 }, { 49, 63, 0 } } }, - { { { 54, 0, 1 }, { 58, 46, 0 } } }, - { { { 54, 0, 0 }, { 50, 62, 0 } } }, - { { { 54, 0, 1 }, { 50, 63, 0 } } }, - { { { 54, 0, 2 }, { 51, 62, 0 } } }, - { { { 55, 0, 1 }, { 59, 47, 0 } } }, - { { { 55, 0, 0 }, { 51, 63, 0 } } }, - { { { 55, 0, 1 }, { 52, 62, 0 } } }, - { { { 55, 0, 2 }, { 52, 63, 0 } } }, - { { { 56, 0, 1 }, { 61, 46, 0 } } }, - { { { 56, 0, 0 }, { 53, 62, 0 } } }, - { { { 56, 0, 1 }, { 53, 63, 0 } } }, - { { { 56, 0, 2 }, { 54, 62, 0 } } }, - { { { 57, 0, 1 }, { 62, 47, 0 } } }, - { { { 57, 0, 0 }, { 54, 63, 0 } } }, - { { { 57, 0, 1 }, { 55, 62, 0 } } }, - { { { 57, 0, 2 }, { 55, 63, 0 } } }, - { { { 58, 0, 1 }, { 56, 62, 1 } } }, - { { { 58, 0, 0 }, { 56, 62, 0 } } }, - { { { 58, 0, 1 }, { 56, 63, 0 } } }, - { { { 58, 0, 2 }, { 57, 62, 0 } } }, - { { { 59, 0, 1 }, { 57, 63, 1 } } }, - { { { 59, 0, 0 }, { 57, 63, 0 } } }, - { { { 59, 0, 1 }, { 58, 62, 0 } } }, - { { { 59, 0, 2 }, { 58, 63, 0 } } }, - { { { 60, 0, 1 }, { 59, 62, 1 } } }, - { { { 60, 0, 0 }, { 59, 62, 0 } } }, - { { { 60, 0, 1 }, { 59, 63, 0 } } }, - { { { 60, 0, 2 }, { 60, 62, 0 } } }, - { { { 61, 0, 1 }, { 60, 63, 1 } } }, - { { { 61, 0, 0 }, { 60, 63, 0 } } }, - { { { 61, 0, 1 }, { 61, 62, 0 } } }, - { { { 61, 0, 2 }, { 61, 63, 0 } } }, - { { { 62, 0, 1 }, { 62, 62, 1 } } }, - { { { 62, 0, 0 }, { 62, 62, 0 } } }, - { { { 62, 0, 1 }, { 62, 63, 0 } } }, - { { { 62, 0, 2 }, { 63, 62, 0 } } }, - { { { 63, 0, 1 }, { 63, 63, 1 } } }, - { { { 63, 0, 0 }, { 63, 63, 0 } } } -}; diff --git a/thirdparty/squish/squish.cpp b/thirdparty/squish/squish.cpp deleted file mode 100644 index 1de1da3e52..0000000000 --- a/thirdparty/squish/squish.cpp +++ /dev/null @@ -1,411 +0,0 @@ -/* ----------------------------------------------------------------------------- - - Copyright (c) 2006 Simon Brown si@sjbrown.co.uk - - 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 <string.h> -#include "squish.h" -#include "colourset.h" -#include "maths.h" -#include "rangefit.h" -#include "clusterfit.h" -#include "colourblock.h" -#include "alpha.h" -#include "singlecolourfit.h" - -namespace squish { - -static int FixFlags( int flags ) -{ - // grab the flag bits - int method = flags & ( kDxt1 | kDxt3 | kDxt5 | kBc4 | kBc5 ); - int fit = flags & ( kColourIterativeClusterFit | kColourClusterFit | kColourRangeFit ); - int extra = flags & kWeightColourByAlpha; - - // set defaults - if ( method != kDxt3 - && method != kDxt5 - && method != kBc4 - && method != kBc5 ) - { - method = kDxt1; - } - if( fit != kColourRangeFit && fit != kColourIterativeClusterFit ) - fit = kColourClusterFit; - - // done - return method | fit | extra; -} - -void CompressMasked( u8 const* rgba, int mask, void* block, int flags, float* metric ) -{ - // fix any bad flags - flags = FixFlags( flags ); - - if ( ( flags & ( kBc4 | kBc5 ) ) != 0 ) - { - u8 alpha[16*4]; - for( int i = 0; i < 16; ++i ) - { - alpha[i*4 + 3] = rgba[i*4 + 0]; // copy R to A - } - - u8* rBlock = reinterpret_cast< u8* >( block ); - CompressAlphaDxt5( alpha, mask, rBlock ); - - if ( ( flags & ( kBc5 ) ) != 0 ) - { - for( int i = 0; i < 16; ++i ) - { - alpha[i*4 + 3] = rgba[i*4 + 1]; // copy G to A - } - - u8* gBlock = reinterpret_cast< u8* >( block ) + 8; - CompressAlphaDxt5( alpha, mask, gBlock ); - } - - return; - } - - // get the block locations - void* colourBlock = block; - void* alphaBlock = block; - if( ( flags & ( kDxt3 | kDxt5 ) ) != 0 ) - colourBlock = reinterpret_cast< u8* >( block ) + 8; - - // create the minimal point set - ColourSet colours( rgba, mask, flags ); - - // check the compression type and compress colour - if( colours.GetCount() == 1 ) - { - // always do a single colour fit - SingleColourFit fit( &colours, flags ); - fit.Compress( colourBlock ); - } - else if( ( flags & kColourRangeFit ) != 0 || colours.GetCount() == 0 ) - { - // do a range fit - RangeFit fit( &colours, flags, metric ); - fit.Compress( colourBlock ); - } - else - { - // default to a cluster fit (could be iterative or not) - ClusterFit fit( &colours, flags, metric ); - fit.Compress( colourBlock ); - } - - // compress alpha separately if necessary - if( ( flags & kDxt3 ) != 0 ) - CompressAlphaDxt3( rgba, mask, alphaBlock ); - else if( ( flags & kDxt5 ) != 0 ) - CompressAlphaDxt5( rgba, mask, alphaBlock ); -} - -void Decompress( u8* rgba, void const* block, int flags ) -{ - // fix any bad flags - flags = FixFlags( flags ); - - // get the block locations - void const* colourBlock = block; - void const* alphaBlock = block; - if( ( flags & ( kDxt3 | kDxt5 ) ) != 0 ) - colourBlock = reinterpret_cast< u8 const* >( block ) + 8; - - // decompress colour - // -- GODOT start -- - //DecompressColour( rgba, colourBlock, ( flags & kDxt1 ) != 0 ); - if(( flags & ( kBc4 ) ) != 0) - DecompressColourBc4( rgba, colourBlock); - else if(( flags & ( kBc5 ) ) != 0) - DecompressColourBc5( rgba, colourBlock); - else - DecompressColour( rgba, colourBlock, ( flags & kDxt1 ) != 0 ); - // -- GODOT end -- - - // decompress alpha separately if necessary - if( ( flags & kDxt3 ) != 0 ) - DecompressAlphaDxt3( rgba, alphaBlock ); - else if( ( flags & kDxt5 ) != 0 ) - DecompressAlphaDxt5( rgba, alphaBlock ); -} - -int GetStorageRequirements( int width, int height, int flags ) -{ - // fix any bad flags - flags = FixFlags( flags ); - - // compute the storage requirements - int blockcount = ( ( width + 3 )/4 ) * ( ( height + 3 )/4 ); - int blocksize = ( ( flags & ( kDxt1 | kBc4 ) ) != 0 ) ? 8 : 16; - return blockcount*blocksize; -} - -void CopyRGBA( u8 const* source, u8* dest, int flags ) -{ - if (flags & kSourceBGRA) - { - // convert from bgra to rgba - dest[0] = source[2]; - dest[1] = source[1]; - dest[2] = source[0]; - dest[3] = source[3]; - } - else - { - for( int i = 0; i < 4; ++i ) - *dest++ = *source++; - } -} - -void CompressImage( u8 const* rgba, int width, int height, int pitch, void* blocks, int flags, float* metric ) -{ - // fix any bad flags - flags = FixFlags( flags ); - - // loop over blocks -#ifdef SQUISH_USE_OPENMP -# pragma omp parallel for -#endif - for( int y = 0; y < height; y += 4 ) - { - // initialise the block output - u8* targetBlock = reinterpret_cast< u8* >( blocks ); - int bytesPerBlock = ( ( flags & ( kDxt1 | kBc4 ) ) != 0 ) ? 8 : 16; - targetBlock += ( (y / 4) * ( (width + 3) / 4) ) * bytesPerBlock; - - for( int x = 0; x < width; x += 4 ) - { - // build the 4x4 block of pixels - u8 sourceRgba[16*4]; - u8* targetPixel = sourceRgba; - int mask = 0; - for( int py = 0; py < 4; ++py ) - { - for( int px = 0; px < 4; ++px ) - { - // get the source pixel in the image - int sx = x + px; - int sy = y + py; - - // enable if we're in the image - if( sx < width && sy < height ) - { - // copy the rgba value - u8 const* sourcePixel = rgba + pitch*sy + 4*sx; - CopyRGBA(sourcePixel, targetPixel, flags); - // enable this pixel - mask |= ( 1 << ( 4*py + px ) ); - } - - // advance to the next pixel - targetPixel += 4; - } - } - - // compress it into the output - CompressMasked( sourceRgba, mask, targetBlock, flags, metric ); - - // advance - targetBlock += bytesPerBlock; - } - } -} - -void CompressImage( u8 const* rgba, int width, int height, void* blocks, int flags, float* metric ) -{ - CompressImage(rgba, width, height, width*4, blocks, flags, metric); -} - -void DecompressImage( u8* rgba, int width, int height, int pitch, void const* blocks, int flags ) -{ - // fix any bad flags - flags = FixFlags( flags ); - - // loop over blocks -#ifdef SQUISH_USE_OPENMP -# pragma omp parallel for -#endif - for( int y = 0; y < height; y += 4 ) - { - // initialise the block input - u8 const* sourceBlock = reinterpret_cast< u8 const* >( blocks ); - int bytesPerBlock = ( ( flags & ( kDxt1 | kBc4 ) ) != 0 ) ? 8 : 16; - sourceBlock += ( (y / 4) * ( (width + 3) / 4) ) * bytesPerBlock; - - for( int x = 0; x < width; x += 4 ) - { - // decompress the block - u8 targetRgba[4*16]; - Decompress( targetRgba, sourceBlock, flags ); - - // write the decompressed pixels to the correct image locations - u8 const* sourcePixel = targetRgba; - for( int py = 0; py < 4; ++py ) - { - for( int px = 0; px < 4; ++px ) - { - // get the target location - int sx = x + px; - int sy = y + py; - - // write if we're in the image - if( sx < width && sy < height ) - { - // copy the rgba value - u8* targetPixel = rgba + pitch*sy + 4*sx; - CopyRGBA(sourcePixel, targetPixel, flags); - } - - // advance to the next pixel - sourcePixel += 4; - } - } - - // advance - sourceBlock += bytesPerBlock; - } - } -} - -void DecompressImage( u8* rgba, int width, int height, void const* blocks, int flags ) -{ - DecompressImage( rgba, width, height, width*4, blocks, flags ); -} - -static double ErrorSq(double x, double y) -{ - return (x - y) * (x - y); -} - -static void ComputeBlockWMSE(u8 const *original, u8 const *compressed, unsigned int w, unsigned int h, double &cmse, double &amse) -{ - // Computes the MSE for the block and weights it by the variance of the original block. - // If the variance of the original block is less than 4 (i.e. a standard deviation of 1 per channel) - // then the block is close to being a single colour. Quantisation errors in single colour blocks - // are easier to see than similar errors in blocks that contain more colours, particularly when there - // are many such blocks in a large area (eg a blue sky background) as they cause banding. Given that - // banding is easier to see than small errors in "complex" blocks, we weight the errors by a factor - // of 5. This implies that images with large, single colour areas will have a higher potential WMSE - // than images with lots of detail. - - cmse = amse = 0; - unsigned int sum_p[4]; // per channel sum of pixels - unsigned int sum_p2[4]; // per channel sum of pixels squared - memset(sum_p, 0, sizeof(sum_p)); - memset(sum_p2, 0, sizeof(sum_p2)); - for( unsigned int py = 0; py < 4; ++py ) - { - for( unsigned int px = 0; px < 4; ++px ) - { - if( px < w && py < h ) - { - double pixelCMSE = 0; - for( int i = 0; i < 3; ++i ) - { - pixelCMSE += ErrorSq(original[i], compressed[i]); - sum_p[i] += original[i]; - sum_p2[i] += (unsigned int)original[i]*original[i]; - } - if( original[3] == 0 && compressed[3] == 0 ) - pixelCMSE = 0; // transparent in both, so colour is inconsequential - amse += ErrorSq(original[3], compressed[3]); - cmse += pixelCMSE; - sum_p[3] += original[3]; - sum_p2[3] += (unsigned int)original[3]*original[3]; - } - original += 4; - compressed += 4; - } - } - unsigned int variance = 0; - for( int i = 0; i < 4; ++i ) - variance += w*h*sum_p2[i] - sum_p[i]*sum_p[i]; - if( variance < 4 * w * w * h * h ) - { - amse *= 5; - cmse *= 5; - } -} - -void ComputeMSE( u8 const *rgba, int width, int height, int pitch, u8 const *dxt, int flags, double &colourMSE, double &alphaMSE ) -{ - // fix any bad flags - flags = FixFlags( flags ); - colourMSE = alphaMSE = 0; - - // initialise the block input - squish::u8 const* sourceBlock = dxt; - int bytesPerBlock = ( ( flags & squish::kDxt1 ) != 0 ) ? 8 : 16; - - // loop over blocks - for( int y = 0; y < height; y += 4 ) - { - for( int x = 0; x < width; x += 4 ) - { - // decompress the block - u8 targetRgba[4*16]; - Decompress( targetRgba, sourceBlock, flags ); - u8 const* sourcePixel = targetRgba; - - // copy across to a similar pixel block - u8 originalRgba[4*16]; - u8* originalPixel = originalRgba; - - for( int py = 0; py < 4; ++py ) - { - for( int px = 0; px < 4; ++px ) - { - int sx = x + px; - int sy = y + py; - if( sx < width && sy < height ) - { - u8 const* targetPixel = rgba + pitch*sy + 4*sx; - CopyRGBA(targetPixel, originalPixel, flags); - } - sourcePixel += 4; - originalPixel += 4; - } - } - - // compute the weighted MSE of the block - double blockCMSE, blockAMSE; - ComputeBlockWMSE(originalRgba, targetRgba, std::min(4, width - x), std::min(4, height - y), blockCMSE, blockAMSE); - colourMSE += blockCMSE; - alphaMSE += blockAMSE; - // advance - sourceBlock += bytesPerBlock; - } - } - colourMSE /= (width * height * 3); - alphaMSE /= (width * height); -} - -void ComputeMSE( u8 const *rgba, int width, int height, u8 const *dxt, int flags, double &colourMSE, double &alphaMSE ) -{ - ComputeMSE(rgba, width, height, width*4, dxt, flags, colourMSE, alphaMSE); -} - -} // namespace squish diff --git a/thirdparty/squish/squish.h b/thirdparty/squish/squish.h deleted file mode 100644 index 14c9bb59fb..0000000000 --- a/thirdparty/squish/squish.h +++ /dev/null @@ -1,309 +0,0 @@ -/* ----------------------------------------------------------------------------- - - Copyright (c) 2006 Simon Brown si@sjbrown.co.uk - - 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 SQUISH_H -#define SQUISH_H - -//! All squish API functions live in this namespace. -namespace squish { - -// ----------------------------------------------------------------------------- - -//! Typedef a quantity that is a single unsigned byte. -typedef unsigned char u8; - -// ----------------------------------------------------------------------------- - -enum -{ - //! Use DXT1 compression. - kDxt1 = ( 1 << 0 ), - - //! Use DXT3 compression. - kDxt3 = ( 1 << 1 ), - - //! Use DXT5 compression. - kDxt5 = ( 1 << 2 ), - - //! Use BC4 compression. - kBc4 = ( 1 << 3 ), - - //! Use BC5 compression. - kBc5 = ( 1 << 4 ), - - //! Use a slow but high quality colour compressor (the default). - kColourClusterFit = ( 1 << 5 ), - - //! Use a fast but low quality colour compressor. - kColourRangeFit = ( 1 << 6 ), - - //! Weight the colour by alpha during cluster fit (disabled by default). - kWeightColourByAlpha = ( 1 << 7 ), - - //! Use a very slow but very high quality colour compressor. - kColourIterativeClusterFit = ( 1 << 8 ), - - //! Source is BGRA rather than RGBA - kSourceBGRA = ( 1 << 9 ) -}; - -// ----------------------------------------------------------------------------- - -/*! @brief Compresses a 4x4 block of pixels. - - @param rgba The rgba values of the 16 source pixels. - @param mask The valid pixel mask. - @param block Storage for the compressed DXT block. - @param flags Compression flags. - @param metric An optional perceptual metric. - - The source pixels should be presented as a contiguous array of 16 rgba - values, with each component as 1 byte each. In memory this should be: - - { r1, g1, b1, a1, .... , r16, g16, b16, a16 } - - The mask parameter enables only certain pixels within the block. The lowest - bit enables the first pixel and so on up to the 16th bit. Bits beyond the - 16th bit are ignored. Pixels that are not enabled are allowed to take - arbitrary colours in the output block. An example of how this can be used - is in the CompressImage function to disable pixels outside the bounds of - the image when the width or height is not divisible by 4. - - The flags parameter should specify kDxt1, kDxt3, kDxt5, kBc4, or kBc5 compression, - however, DXT1 will be used by default if none is specified. When using DXT1 - compression, 8 bytes of storage are required for the compressed DXT block. - DXT3 and DXT5 compression require 16 bytes of storage per block. - - The flags parameter can also specify a preferred colour compressor to use - when fitting the RGB components of the data. Possible colour compressors - are: kColourClusterFit (the default), kColourRangeFit (very fast, low - quality) or kColourIterativeClusterFit (slowest, best quality). - - When using kColourClusterFit or kColourIterativeClusterFit, an additional - flag can be specified to weight the importance of each pixel by its alpha - value. For images that are rendered using alpha blending, this can - significantly increase the perceived quality. - - The metric parameter can be used to weight the relative importance of each - colour channel, or pass NULL to use the default uniform weight of - { 1.0f, 1.0f, 1.0f }. This replaces the previous flag-based control that - allowed either uniform or "perceptual" weights with the fixed values - { 0.2126f, 0.7152f, 0.0722f }. If non-NULL, the metric should point to a - contiguous array of 3 floats. -*/ -void CompressMasked( u8 const* rgba, int mask, void* block, int flags, float* metric = 0 ); - -// ----------------------------------------------------------------------------- - -/*! @brief Compresses a 4x4 block of pixels. - - @param rgba The rgba values of the 16 source pixels. - @param block Storage for the compressed DXT block. - @param flags Compression flags. - @param metric An optional perceptual metric. - - The source pixels should be presented as a contiguous array of 16 rgba - values, with each component as 1 byte each. In memory this should be: - - { r1, g1, b1, a1, .... , r16, g16, b16, a16 } - - The flags parameter should specify kDxt1, kDxt3, kDxt5, kBc4, or kBc5 compression, - however, DXT1 will be used by default if none is specified. When using DXT1 - compression, 8 bytes of storage are required for the compressed DXT block. - DXT3 and DXT5 compression require 16 bytes of storage per block. - - The flags parameter can also specify a preferred colour compressor to use - when fitting the RGB components of the data. Possible colour compressors - are: kColourClusterFit (the default), kColourRangeFit (very fast, low - quality) or kColourIterativeClusterFit (slowest, best quality). - - When using kColourClusterFit or kColourIterativeClusterFit, an additional - flag can be specified to weight the importance of each pixel by its alpha - value. For images that are rendered using alpha blending, this can - significantly increase the perceived quality. - - The metric parameter can be used to weight the relative importance of each - colour channel, or pass NULL to use the default uniform weight of - { 1.0f, 1.0f, 1.0f }. This replaces the previous flag-based control that - allowed either uniform or "perceptual" weights with the fixed values - { 0.2126f, 0.7152f, 0.0722f }. If non-NULL, the metric should point to a - contiguous array of 3 floats. - - This method is an inline that calls CompressMasked with a mask of 0xffff, - provided for compatibility with older versions of squish. -*/ -inline void Compress( u8 const* rgba, void* block, int flags, float* metric = 0 ) -{ - CompressMasked( rgba, 0xffff, block, flags, metric ); -} - -// ----------------------------------------------------------------------------- - -/*! @brief Decompresses a 4x4 block of pixels. - - @param rgba Storage for the 16 decompressed pixels. - @param block The compressed DXT block. - @param flags Compression flags. - - The decompressed pixels will be written as a contiguous array of 16 rgba - values, with each component as 1 byte each. In memory this is: - - { r1, g1, b1, a1, .... , r16, g16, b16, a16 } - - The flags parameter should specify kDxt1, kDxt3, kDxt5, kBc4, or kBc5 compression, - however, DXT1 will be used by default if none is specified. All other flags - are ignored. -*/ -void Decompress( u8* rgba, void const* block, int flags ); - -// ----------------------------------------------------------------------------- - -/*! @brief Computes the amount of compressed storage required. - - @param width The width of the image. - @param height The height of the image. - @param flags Compression flags. - - The flags parameter should specify kDxt1, kDxt3, kDxt5, kBc4, or kBc5 compression, - however, DXT1 will be used by default if none is specified. All other flags - are ignored. - - Most DXT images will be a multiple of 4 in each dimension, but this - function supports arbitrary size images by allowing the outer blocks to - be only partially used. -*/ -int GetStorageRequirements( int width, int height, int flags ); - -// ----------------------------------------------------------------------------- - -/*! @brief Compresses an image in memory. - - @param rgba The pixels of the source. - @param width The width of the source image. - @param height The height of the source image. - @param pitch The pitch of the source image. - @param blocks Storage for the compressed output. - @param flags Compression flags. - @param metric An optional perceptual metric. - - The source pixels should be presented as a contiguous array of width*height - rgba values, with each component as 1 byte each. In memory this should be: - - { r1, g1, b1, a1, .... , rn, gn, bn, an } for n = width*height - - The flags parameter should specify kDxt1, kDxt3, kDxt5, kBc4, or kBc5 compression, - however, DXT1 will be used by default if none is specified. When using DXT1 - compression, 8 bytes of storage are required for each compressed DXT block. - DXT3 and DXT5 compression require 16 bytes of storage per block. - - The flags parameter can also specify a preferred colour compressor to use - when fitting the RGB components of the data. Possible colour compressors - are: kColourClusterFit (the default), kColourRangeFit (very fast, low - quality) or kColourIterativeClusterFit (slowest, best quality). - - When using kColourClusterFit or kColourIterativeClusterFit, an additional - flag can be specified to weight the importance of each pixel by its alpha - value. For images that are rendered using alpha blending, this can - significantly increase the perceived quality. - - The metric parameter can be used to weight the relative importance of each - colour channel, or pass NULL to use the default uniform weight of - { 1.0f, 1.0f, 1.0f }. This replaces the previous flag-based control that - allowed either uniform or "perceptual" weights with the fixed values - { 0.2126f, 0.7152f, 0.0722f }. If non-NULL, the metric should point to a - contiguous array of 3 floats. - - Internally this function calls squish::CompressMasked for each block, which - allows for pixels outside the image to take arbitrary values. The function - squish::GetStorageRequirements can be called to compute the amount of memory - to allocate for the compressed output. - - Note on compression quality: When compressing textures with - libsquish it is recommended to apply a gamma-correction - beforehand. This will reduce the blockiness in dark areas. The - level of necessary gamma-correction is platform dependent. For - example, a gamma correction with gamma = 0.5 before compression - and gamma = 2.0 after decompression yields good results on the - Windows platform but for other platforms like MacOS X a different - gamma value may be more suitable. -*/ -void CompressImage( u8 const* rgba, int width, int height, int pitch, void* blocks, int flags, float* metric = 0 ); -void CompressImage( u8 const* rgba, int width, int height, void* blocks, int flags, float* metric = 0 ); - -// ----------------------------------------------------------------------------- - -/*! @brief Decompresses an image in memory. - - @param rgba Storage for the decompressed pixels. - @param width The width of the source image. - @param height The height of the source image. - @param pitch The pitch of the decompressed pixels. - @param blocks The compressed DXT blocks. - @param flags Compression flags. - - The decompressed pixels will be written as a contiguous array of width*height - 16 rgba values, with each component as 1 byte each. In memory this is: - - { r1, g1, b1, a1, .... , rn, gn, bn, an } for n = width*height - - The flags parameter should specify kDxt1, kDxt3, kDxt5, kBc4, or kBc5 compression, - however, DXT1 will be used by default if none is specified. All other flags - are ignored. - - Internally this function calls squish::Decompress for each block. -*/ -void DecompressImage( u8* rgba, int width, int height, int pitch, void const* blocks, int flags ); -void DecompressImage( u8* rgba, int width, int height, void const* blocks, int flags ); - -// ----------------------------------------------------------------------------- - -/*! @brief Computes MSE of an compressed image in memory. - - @param rgba The original image pixels. - @param width The width of the source image. - @param height The height of the source image. - @param pitch The pitch of the source image. - @param dxt The compressed dxt blocks - @param flags Compression flags. - @param colourMSE The MSE of the colour values. - @param alphaMSE The MSE of the alpha values. - - The colour MSE and alpha MSE are computed across all pixels. The colour MSE is - averaged across all rgb values (i.e. colourMSE = sum sum_k ||dxt.k - rgba.k||/3) - - The flags parameter should specify kDxt1, kDxt3, kDxt5, kBc4, or kBc5 compression, - however, DXT1 will be used by default if none is specified. All other flags - are ignored. - - Internally this function calls squish::Decompress for each block. -*/ -void ComputeMSE(u8 const *rgba, int width, int height, int pitch, u8 const *dxt, int flags, double &colourMSE, double &alphaMSE); -void ComputeMSE(u8 const *rgba, int width, int height, u8 const *dxt, int flags, double &colourMSE, double &alphaMSE); - -// ----------------------------------------------------------------------------- - -} // namespace squish - -#endif // ndef SQUISH_H |