| // Copyright 2022 The clvk authors. |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| #include <cstring> |
| |
| #include "device_properties.hpp" |
| #include "log.hpp" |
| |
| #ifdef __ANDROID__ |
| #include <sys/system_properties.h> |
| #endif |
| |
| struct cvk_device_properties_mali : public cvk_device_properties { |
| std::string vendor() const override final { return "ARM"; } |
| cl_uint get_max_first_cmd_batch_size() const override final { return 10; } |
| cl_uint get_max_cmd_group_size() const override final { return 1; } |
| |
| cvk_device_properties_mali(const uint32_t deviceID) |
| : m_deviceID(deviceID) {} |
| |
| bool is_non_uniform_decoration_broken() const override final { |
| #define GPU_ID2_ARCH_MAJOR_SHIFT 28 |
| #define GPU_ID2_ARCH_MAJOR (0xF << GPU_ID2_ARCH_MAJOR_SHIFT) |
| // bifrost support of non uniform decoration is broken |
| const uint32_t bifrost_arch_major = 8 << GPU_ID2_ARCH_MAJOR_SHIFT; |
| return (m_deviceID & GPU_ID2_ARCH_MAJOR) <= bifrost_arch_major; |
| } |
| |
| private: |
| const uint32_t m_deviceID; |
| }; |
| |
| struct cvk_device_properties_mali_exynos9820 |
| : public cvk_device_properties_mali { |
| cl_ulong get_global_mem_cache_size() const override final { return 262144; } |
| cl_ulong get_num_compute_units() const override final { return 12; } |
| cvk_device_properties_mali_exynos9820(const uint32_t deviceID) |
| : cvk_device_properties_mali(deviceID) {} |
| }; |
| |
| struct cvk_device_properties_mali_exynos990 |
| : public cvk_device_properties_mali { |
| cl_ulong get_global_mem_cache_size() const override final { return 262144; } |
| cl_ulong get_num_compute_units() const override final { return 11; } |
| cvk_device_properties_mali_exynos990(const uint32_t deviceID) |
| : cvk_device_properties_mali(deviceID) {} |
| }; |
| |
| static bool isMaliDevice(const char* name, const uint32_t vendorID) { |
| const uint32_t ARMVendorID = 0x13B5; |
| return vendorID == ARMVendorID || strncmp(name, "Mali-", 5) == 0; |
| } |
| |
| struct cvk_device_properties_adreno : public cvk_device_properties { |
| std::string vendor() const override final { return "Qualcomm"; } |
| }; |
| |
| struct cvk_device_properties_adreno_615 : public cvk_device_properties_adreno { |
| cl_ulong get_global_mem_cache_size() const override final { return 65536; } |
| cl_ulong get_num_compute_units() const override final { return 1; } |
| }; |
| |
| struct cvk_device_properties_adreno_620 : public cvk_device_properties_adreno { |
| cl_ulong get_global_mem_cache_size() const override final { return 65536; } |
| cl_ulong get_num_compute_units() const override final { return 1; } |
| }; |
| |
| struct cvk_device_properties_adreno_630 : public cvk_device_properties_adreno { |
| cl_ulong get_global_mem_cache_size() const override final { return 131072; } |
| cl_ulong get_num_compute_units() const override final { return 2; } |
| }; |
| |
| struct cvk_device_properties_adreno_640 : public cvk_device_properties_adreno { |
| cl_ulong get_global_mem_cache_size() const override final { return 131072; } |
| cl_ulong get_num_compute_units() const override final { return 2; } |
| }; |
| |
| struct cvk_device_properties_intel : public cvk_device_properties { |
| std::string vendor() const override final { return "Intel Corporation"; } |
| cl_uint get_max_first_cmd_batch_size() const override final { return 10; } |
| cl_uint get_max_cmd_group_size() const override final { return 1; } |
| const std::set<std::string> get_native_builtins() const override final { |
| return std::set<std::string>({ |
| "ceil", "copysign", "exp2", "floor", |
| "fma", "fmax", "fmin", "half_exp", |
| "half_exp10", "half_exp2", "half_log", "half_log10", |
| "half_log2", "half_powr", "half_rsqrt", "half_sqrt", |
| "isequal", "isfinite", "isgreater", "isgreaterequal", |
| "isinf", "isless", "islessequal", "islessgreater", |
| "isnan", "isnormal", "isnotequal", "isordered", |
| "isunordered", "mad", "rint", "round", |
| "rsqrt", "signbit", "sqrt", "trunc", |
| }); |
| } |
| std::string get_compile_options() const override final { |
| return "-hack-mul-extended -hack-convert-to-float " |
| "-hack-image1d-buffer-bgra"; |
| } |
| uint32_t get_preferred_subgroup_size() const override final { return 16; } |
| bool |
| is_bgra_format_not_supported_for_image1d_buffer() const override final { |
| return true; |
| } |
| |
| const image_format_set& get_disabled_image_formats() const override final { |
| static image_format_set disabled_formats( |
| {{CL_RGB, CL_UNORM_SHORT_565}}); |
| return disabled_formats; |
| } |
| }; |
| |
| static bool isIntelDevice(const char* name, const uint32_t vendorID) { |
| const uint32_t IntelVendorID = 0x8086; |
| return vendorID == IntelVendorID || strncmp(name, "Intel", 5) == 0; |
| } |
| |
| struct cvk_device_properties_amd : public cvk_device_properties { |
| std::string vendor() const override final { |
| return "Advanced Micro Devices, Inc. [AMD/ATI]"; |
| } |
| cl_uint get_max_first_cmd_batch_size() const override final { return 10; } |
| cl_uint get_max_cmd_group_size() const override final { return 1; } |
| const std::set<std::string> get_native_builtins() const override final { |
| return std::set<std::string>({ |
| "ceil", "copysign", "exp2", "fdim", |
| "floor", "fmax", "fmin", "frexp", |
| "half_exp", "half_exp10", "half_exp2", "half_log", |
| "half_log10", "half_log2", "half_powr", "half_rsqrt", |
| "half_sqrt", "isequal", "isfinite", "isgreater", |
| "isgreaterequal", "isinf", "isless", "islessequal", |
| "islessgreater", "isnan", "isnormal", "isnotequal", |
| "isordered", "isunordered", "ldexp", "log", |
| "log10", "log2", "mad", "rint", |
| "round", "rsqrt", "signbit", "sqrt", |
| "trunc", |
| }); |
| } |
| std::string get_compile_options() const override final { |
| return "-hack-convert-to-float"; |
| } |
| }; |
| |
| static bool isAMDDevice(const char* name, const uint32_t vendorID) { |
| const uint32_t AMDVendorID = 0x1002; |
| return vendorID == AMDVendorID || strncmp(name, "AMD", 3) == 0; |
| } |
| |
| struct cvk_device_properties_samsung_xclipse_920 |
| : public cvk_device_properties { |
| std::string vendor() const override final { return "Samsung"; } |
| const std::set<std::string> get_native_builtins() const override final { |
| return std::set<std::string>({ |
| "ceil", "floor", "fma", "fmax", |
| "fmin", "half_exp2", "half_log2", "half_rsqrt", |
| "half_sqrt", "isequal", "isgreater", "isgreaterequal", |
| "isless", "islessequal", "islessgreater", "isnotequal", |
| "log2", "mad", "round", "rsqrt", |
| "sqrt", "exp2", |
| }); |
| } |
| }; |
| |
| struct cvk_device_properties_swiftshader : public cvk_device_properties { |
| std::string vendor() const override final { return "Google, Inc."; } |
| const std::set<std::string> get_native_builtins() const override final { |
| return std::set<std::string>({ |
| "asin", "asinpi", "atan", |
| "atanpi", "ceil", "copysign", |
| "fabs", "fdim", "floor", |
| "fma", "fmax", "fmin", |
| "fmod", "half_rsqrt", "half_sqrt", |
| "isequal", "isgreater", "isgreaterequal", |
| "isinf", "isless", "islessequal", |
| "islessgreater", "isnan", "isnormal", |
| "isnotequal", "isordered", "isunordered", |
| "mad", "rint", "round", |
| "rsqrt", "signbit", "sqrt", |
| "trunc", |
| }); |
| } |
| }; |
| |
| static bool isSwiftShaderDevice(const char* name, const uint32_t vendorID, |
| const uint32_t deviceID) { |
| const uint32_t SwiftshaderDeviceID = 0xc0de; |
| const uint32_t SwiftshaderVendorID = 0x1ae0; |
| return (vendorID == SwiftshaderVendorID && |
| deviceID == SwiftshaderDeviceID) || |
| strncmp(name, "SwiftShader Device", 18) == 0; |
| } |
| |
| struct cvk_device_properties_llvmpipe : public cvk_device_properties { |
| std::string vendor() const override final { return "Mesa"; } |
| const std::set<std::string> get_native_builtins() const override final { |
| return std::set<std::string>({ |
| "ceil", "copysign", "fabs", "fdim", |
| "floor", "fmax", "fmin", "isequal", |
| "isfinite", "isgreater", "isgreaterequal", "isinf", |
| "isless", "islessequal", "islessgreater", "isnan", |
| "isnormal", "isnotequal", "isordered", "isunordered", |
| "mad", "rint", "round", "rsqrt", |
| "signbit", "sqrt", "trunc", "half_cos", |
| "half_exp", "half_exp2", "half_exp10", "half_rsqrt", |
| "half_sin", "half_sqrt", "half_tan", |
| }); |
| } |
| std::string get_compile_options() const override final { |
| return "-hack-convert-to-float"; |
| } |
| }; |
| |
| static bool isllvmpipeDevice(const uint32_t vendorID) { |
| return vendorID == 0x10005; |
| } |
| |
| struct cvk_device_properties_nvidia : public cvk_device_properties { |
| std::string vendor() const override final { return "NVIDIA Corporation"; } |
| const std::set<std::string> get_native_builtins() const override final { |
| return std::set<std::string>({ |
| "acos", "acosh", "acospi", "asin", |
| "asinh", "asinpi", "atan", "atan2", |
| "atan2pi", "atanh", "atanpi", "ceil", |
| "copysign", "fdim", "floor", "fma", |
| "fmax", "fmin", "half_rsqrt", "half_sqrt", |
| "isequal", "isfinite", "isgreater", "isgreaterequal", |
| "isinf", "isless", "islessequal", "islessgreater", |
| "isnan", "isnormal", "isnotequal", "isordered", |
| "isunordered", "ldexp", "mad", "rint", |
| "round", "rsqrt", "signbit", "sqrt", |
| "tanh", "trunc", |
| }); |
| } |
| }; |
| |
| static bool isNVIDIADevice(const uint32_t vendorID) { |
| const uint32_t NVIDIAVendorID = 0x10de; |
| return vendorID == NVIDIAVendorID; |
| } |
| |
| #define RETURN(x, ...) \ |
| cvk_info_fn(#x); \ |
| return std::make_unique<x>(__VA_ARGS__); |
| |
| std::unique_ptr<cvk_device_properties> create_cvk_device_properties( |
| const char* name, const uint32_t vendorID, const uint32_t deviceID, |
| const uint32_t driverVersion, const VkDriverId driverID) { |
| if (isMaliDevice(name, vendorID)) { |
| #ifdef __ANDROID__ |
| // Find out which SoC this is. |
| char soc[PROP_VALUE_MAX + 1]; |
| int len = __system_property_get("ro.hardware", soc); |
| if (len == 0) { |
| cvk_warn("Unable to query 'ro.hardware' system property, some " |
| "device properties will be incorrect."); |
| } else if (strcmp(soc, "exynos9820") == 0) { |
| RETURN(cvk_device_properties_mali_exynos9820, deviceID); |
| } else if (strcmp(soc, "exynos990") == 0) { |
| RETURN(cvk_device_properties_mali_exynos990, deviceID); |
| } else { |
| cvk_warn("Unrecognized 'ro.hardware' value '%s', some device " |
| "properties will be incorrect.", |
| soc); |
| } |
| #else |
| cvk_warn("Unrecognized Mali device, some device properties will be " |
| "incorrect."); |
| #endif |
| RETURN(cvk_device_properties_mali, deviceID); |
| } else if (strcmp(name, "Adreno (TM) 615") == 0) { |
| RETURN(cvk_device_properties_adreno_615); |
| } else if (strcmp(name, "Adreno (TM) 620") == 0) { |
| RETURN(cvk_device_properties_adreno_620); |
| } else if (strcmp(name, "Adreno (TM) 630") == 0) { |
| RETURN(cvk_device_properties_adreno_630); |
| } else if (strcmp(name, "Adreno (TM) 640") == 0) { |
| RETURN(cvk_device_properties_adreno_640); |
| } else if (isIntelDevice(name, vendorID)) { |
| RETURN(cvk_device_properties_intel); |
| } else if (isAMDDevice(name, vendorID)) { |
| RETURN(cvk_device_properties_amd); |
| } else if (strcmp(name, "Samsung Xclipse 920") == 0) { |
| RETURN(cvk_device_properties_samsung_xclipse_920); |
| } else if (isSwiftShaderDevice(name, vendorID, deviceID)) { |
| RETURN(cvk_device_properties_swiftshader); |
| } else if (isNVIDIADevice(vendorID)) { |
| RETURN(cvk_device_properties_nvidia); |
| } else if (isllvmpipeDevice(vendorID)) { |
| RETURN(cvk_device_properties_llvmpipe); |
| } else { |
| cvk_warn("Unrecognized device '%s' (vendorID '0x%x' - deviceID " |
| "'0x%x'), some device properties will be " |
| "incorrect.", |
| name, vendorID, deviceID); |
| } |
| |
| RETURN(cvk_device_properties); |
| } |