返回> 网站首页 

vulkan功能支持检测 - 编译安卓应用程序

yoours2025-09-11 18:27:10 阅读 27

简介一边听听音乐,一边写写文章。

一、vulkan功能支持检测

//#define VK_NO_PROTOTYPES

#include <vulkan/vulkan.h>

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <android/log.h>


// Android日志标签

#define LOG_TAG "VulkanInfo"

#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)

#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)


// 打印Vulkan版本信息

void print_vulkan_version() {

    uint32_t api_version = VK_API_VERSION_1_0;

    VkResult result = vkEnumerateInstanceVersion(&api_version);

    if (result != VK_SUCCESS) {

        LOGI("获取Vulkan版本失败: %d", result);

        api_version = VK_API_VERSION_1_0;

    }


    LOGI("Vulkan API版本: %d.%d.%d", 

         VK_API_VERSION_MAJOR(api_version),

         VK_API_VERSION_MINOR(api_version),

         VK_API_VERSION_PATCH(api_version));

}


// 检查扩展是否可用

int check_extension_available(const char* extension_name, VkPhysicalDevice device) {

    uint32_t extension_count = 0;

    VkResult result = vkEnumerateDeviceExtensionProperties(device, NULL, &extension_count, NULL);

    if (result != VK_SUCCESS && result != VK_INCOMPLETE) {

        return 0;

    }


    if (extension_count == 0) {

        return 0;

    }


    VkExtensionProperties* extensions = malloc(sizeof(VkExtensionProperties) * extension_count);

    result = vkEnumerateDeviceExtensionProperties(device, NULL, &extension_count, extensions);

    if (result != VK_SUCCESS) {

        free(extensions);

        return 0;

    }


    int found = 0;

    for (uint32_t i = 0; i < extension_count; i++) {

        if (strcmp(extensions[i].extensionName, extension_name) == 0) {

            found = 1;

            break;

        }

    }


    free(extensions);

    return found;

}


// 安全地打印数据类型支持信息

void print_datatype_support(VkPhysicalDevice device) {

    VkPhysicalDeviceFeatures features;

    vkGetPhysicalDeviceFeatures(device, &features);


    LOGI("  基本数据类型支持:");

    LOGI("    float32: 支持"); // float32 总是支持

    LOGI("    float64: %s", features.shaderFloat64 ? "支持" : "不支持");

    LOGI("    int32: 支持"); // int32 总是支持

    LOGI("    int64: %s", features.shaderInt64 ? "支持" : "不支持");


    // 检查是否支持VK_KHR_get_physical_device_properties2扩展

    int has_properties2 = check_extension_available(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, device);

    if (has_properties2) {

        LOGI("  扩展数据类型支持 (使用VK_KHR_get_physical_device_properties2):");

        

        // 使用VK_KHR_get_physical_device_properties2扩展安全地获取特性

        VkPhysicalDeviceFeatures2 features2 = {

            .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2

        };


        // 检查是否支持VK_KHR_shader_float16_int8扩展

        if (check_extension_available(VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME, device)) {

            VkPhysicalDeviceShaderFloat16Int8FeaturesKHR float16_int8_features = {

                .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES_KHR

            };

            features2.pNext = &float16_int8_features;


            vkGetPhysicalDeviceFeatures2(device, &features2);


            LOGI("    float16: %s", float16_int8_features.shaderFloat16 ? "支持" : "不支持");

            LOGI("    int8: %s", float16_int8_features.shaderInt8 ? "支持" : "不支持");

        } else {

            LOGI("    float16: 扩展不可用");

            LOGI("    int8: 扩展不可用");

        }

    } else {

        LOGI("  扩展数据类型支持: VK_KHR_get_physical_device_properties2 不可用");

        LOGI("    float16: 需要扩展支持");

        LOGI("    int8: 需要扩展支持");

    }

}


// 打印物理设备信息

void print_physical_devices(VkInstance instance) {

   

    uint32_t device_count = 0;

    VkResult result = vkEnumeratePhysicalDevices(instance, &device_count, NULL);

    if (result != VK_SUCCESS && result != VK_INCOMPLETE) {

        LOGE("枚举物理设备失败: %d", result);

        return;

    }


    if (device_count == 0) {

        LOGI("未找到支持Vulkan的物理设备");

        return;

    }


    VkPhysicalDevice* devices = malloc(sizeof(VkPhysicalDevice) * device_count);

    result = vkEnumeratePhysicalDevices(instance, &device_count, devices);

    if (result != VK_SUCCESS) {

        LOGE("获取物理设备失败: %d", result);

        free(devices);

        return;

    }


    LOGI("找到 %d 个Vulkan物理设备:", device_count);


    for (uint32_t i = 0; i < device_count; i++) {

        VkPhysicalDeviceProperties props;

        vkGetPhysicalDeviceProperties(devices[i], &props);


        LOGI("设备 %d: %s", i, props.deviceName);

        LOGI("  类型: ");

        switch (props.deviceType) {

            case VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU: LOGI("集成GPU"); break;

            case VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU: LOGI("独立GPU"); break;

            case VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU: LOGI("虚拟GPU"); break;

            case VK_PHYSICAL_DEVICE_TYPE_CPU: LOGI("CPU"); break;

            default: LOGI("其他"); break;

        }


        LOGI("  API版本: %d.%d.%d", 

             VK_API_VERSION_MAJOR(props.apiVersion),

             VK_API_VERSION_MINOR(props.apiVersion),

             VK_API_VERSION_PATCH(props.apiVersion));


        LOGI("  驱动程序版本: %d", props.driverVersion);

        LOGI("  供应商ID: 0x%04X", props.vendorID);

        LOGI("  设备ID: 0x%04X", props.deviceID);


        // 打印设备特性

        VkPhysicalDeviceFeatures features;

        vkGetPhysicalDeviceFeatures(devices[i], &features);


        LOGI("  设备特性:");

        LOGI("    几何着色器: %s", features.geometryShader ? "支持" : "不支持");

        LOGI("    曲面细分着色器: %s", features.tessellationShader ? "支持" : "不支持");

        LOGI("    多视口: %s", features.multiViewport ? "支持" : "不支持");

        LOGI("    采样率遮罩: %s", features.sampleRateShading ? "支持" : "不支持");


        // 打印数据类型支持

        print_datatype_support(devices[i]);


        // 打印队列家族属性

        uint32_t queue_family_count = 0;

        vkGetPhysicalDeviceQueueFamilyProperties(devices[i], &queue_family_count, NULL);


        VkQueueFamilyProperties* queue_families = malloc(sizeof(VkQueueFamilyProperties) * queue_family_count);

        vkGetPhysicalDeviceQueueFamilyProperties(devices[i], &queue_family_count, queue_families);


        LOGI("  队列家族 (%d):", queue_family_count);

        for (uint32_t j = 0; j < queue_family_count; j++) {

            char queue_info[256];

            snprintf(queue_info, sizeof(queue_info), "家族 %d: %d 个队列", j, queue_families[j].queueCount);


            if (queue_families[j].queueFlags & VK_QUEUE_GRAPHICS_BIT) strcat(queue_info, " [图形]");

            if (queue_families[j].queueFlags & VK_QUEUE_COMPUTE_BIT) strcat(queue_info, " [计算]");

            if (queue_families[j].queueFlags & VK_QUEUE_TRANSFER_BIT) strcat(queue_info, " [传输]");

            if (queue_families[j].queueFlags & VK_QUEUE_SPARSE_BINDING_BIT) strcat(queue_info, " [稀疏绑定]");


            LOGI("    %s", queue_info);

        }


        free(queue_families);

    }


    free(devices);

}


int main() {

    LOGI("=== Vulkan 支持检测程序 (Android) ===");


    // 打印Vulkan版本

    print_vulkan_version();


    // 创建Vulkan实例

    VkApplicationInfo app_info = {

        .sType = VK_STRUCTURE_TYPE_APPLICATION_INFO,

        .pApplicationName = "VulkanInfo",

        .applicationVersion = VK_MAKE_VERSION(1, 0, 0),

        .pEngineName = "No Engine",

        .engineVersion = VK_MAKE_VERSION(1, 0, 0),

        .apiVersion = VK_API_VERSION_1_0

    };


    VkInstanceCreateInfo instance_info = {

        .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,

        .pApplicationInfo = &app_info

    };


    VkInstance instance;

    VkResult result = vkCreateInstance(&instance_info, NULL, &instance);

    if (result != VK_SUCCESS) {

        LOGE("创建Vulkan实例失败: %d", result);

        return 1;

    }


    // 打印物理设备信息

    print_physical_devices(instance);

    // 清理

    vkDestroyInstance(instance, NULL);


    LOGI("=== 检测完成 ===");

    return 0;

}


二、编写 CMakeLists.txt

cmake_minimum_required(VERSION 3.4.1)


project(vulkaninfo)


add_executable(vulkaninfo

    vulkan_info.c

)


find_library(VULKAN_LIBRARY vulkan)

if(NOT VULKAN_LIBRARY)

    message(WARNING "vulkan library not found - Vulkan support may not be available")

else()

    message(STATUS "vulkan library found: " ${VULKAN_LIBRARY})

endif()


# 设置编译选项

target_compile_options(vulkaninfo PRIVATE

    -Wimplicit-function-declaration

    -Werror

    -O2

)


target_link_libraries(vulkaninfo

    android

    log

    ${VULKAN_LIBRARY}

    dl

)


set_target_properties(vulkaninfo PROPERTIES

    C_STANDARD 11

    C_STANDARD_REQUIRED ON

)


三、windows下编译
 cmake -DCMAKE_TOOLCHAIN_FILE=D:/Java/Android/android-sdk-windows/ndk/29.0.13846066/build/cmake/android.toolchain.cmake -DANDROID_ABI=arm64-v8a -DANDROID_PLATFORM=android-29 ..
 ninja


四、adb连接android失败

    

    adb默认端口为 5037,检查360的360MobileSrv.exe是否启动,它会占用5037端口导致adb无法使用。

    可使用命令 netstat -ano | findstr 5037 查看占用进程pid,再根据pid查询是哪个程序。


微信小程序扫码登陆

文章评论

27人参与,0条评论