1 /*
2 * Copyright 2020 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 */
17
18 #define LOG_TAG "GpuProfilingData"
19
20 #include <vector>
21
22 #include <android/log.h>
23 #include <dlfcn.h>
24 #include <jni.h>
25 #include <string>
26 #include <vulkan/vulkan.h>
27
28 #define ALOGI(msg, ...) \
29 __android_log_print(ANDROID_LOG_INFO, LOG_TAG, (msg), __VA_ARGS__)
30 #define ALOGE(msg, ...) \
31 __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, (msg), __VA_ARGS__)
32 #define ALOGD(msg, ...) \
33 __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, (msg), __VA_ARGS__)
34 #define REQUIRE_SUCCESS(fn, name) \
35 do { \
36 if (VK_SUCCESS != fn) { \
37 ALOGE("Vulkan Error in %s", name); \
38 return -1; \
39 } \
40 } while (0)
41
42 namespace {
43
44 typedef void (*FN_PTR)(void);
45
initVulkan()46 int initVulkan() {
47 const VkApplicationInfo appInfo = {
48 VK_STRUCTURE_TYPE_APPLICATION_INFO,
49 nullptr, // pNext
50 "GpuProfilingData", // app name
51 0, // app version
52 nullptr, // engine name
53 0, // engine version
54 VK_API_VERSION_1_0,
55 };
56 const VkInstanceCreateInfo instanceInfo = {
57 VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
58 nullptr, // pNext
59 0, // flags
60 &appInfo,
61 0, // layer count
62 nullptr, // layers
63 0, // extension count
64 nullptr, // extensions
65 };
66 VkInstance instance;
67 REQUIRE_SUCCESS(vkCreateInstance(&instanceInfo, nullptr, &instance),
68 "vkCreateInstance");
69
70 VkPhysicalDevice physicalDevice = {};
71 uint32_t nPhysicalDevices;
72 REQUIRE_SUCCESS(
73 vkEnumeratePhysicalDevices(instance, &nPhysicalDevices, nullptr),
74 "vkEnumeratePhysicalDevices");
75 std::vector<VkPhysicalDevice> physicalDevices(nPhysicalDevices);
76
77 REQUIRE_SUCCESS(vkEnumeratePhysicalDevices(instance, &nPhysicalDevices,
78 physicalDevices.data()),
79 "vkEnumeratePhysicalDevices");
80
81 uint32_t queueFamilyIndex = static_cast<uint32_t>(-1);
82 uint32_t i;
83 for (i = 0; i < nPhysicalDevices; ++i) {
84 uint32_t nQueueProperties = 0;
85 vkGetPhysicalDeviceQueueFamilyProperties(physicalDevices[i],
86 &nQueueProperties, nullptr);
87 std::vector<VkQueueFamilyProperties> queueProperties(nQueueProperties);
88 vkGetPhysicalDeviceQueueFamilyProperties(
89 physicalDevices[i], &nQueueProperties, queueProperties.data());
90 for (uint32_t j = 0; j < nQueueProperties; ++j) {
91 if (queueProperties[j].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
92 queueFamilyIndex = j;
93 break;
94 }
95 }
96 if (queueFamilyIndex != static_cast<uint32_t>(-1)) {
97 break;
98 }
99 }
100 if (i == nPhysicalDevices) {
101 ALOGE("%s",
102 "Could not find a physical device that supports a graphics queue");
103 return -1;
104 }
105 physicalDevice = physicalDevices[i];
106
107 float priority = 1.0f;
108 VkDeviceQueueCreateInfo queueCreateInfo{
109 VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
110 nullptr, // pNext
111 0, // flags
112 queueFamilyIndex,
113 1,
114 &priority,
115 };
116
117 VkDeviceCreateInfo deviceCreateInfo{
118 VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
119 nullptr, // pNext
120 0, // flags
121 1,
122 &queueCreateInfo,
123 0,
124 nullptr,
125 0,
126 nullptr,
127 nullptr,
128 };
129
130 VkDevice device;
131
132 REQUIRE_SUCCESS(
133 vkCreateDevice(physicalDevice, &deviceCreateInfo, nullptr, &device),
134 "vkCreateDevice");
135 return 0;
136 }
137
android_graphics_cts_GpuProfilingData_nativeInitVulkan(JNIEnv *,jclass)138 jint android_graphics_cts_GpuProfilingData_nativeInitVulkan(JNIEnv * /*env*/,
139 jclass /*clazz*/) {
140 return (jint)initVulkan();
141 }
142
143 static JNINativeMethod gMethods[] = {
144 {"nativeInitVulkan", "()I",
145 (void *)android_graphics_cts_GpuProfilingData_nativeInitVulkan}};
146 } // anonymous namespace
147
register_android_gputools_cts_GpuProfilingData(JNIEnv * env)148 int register_android_gputools_cts_GpuProfilingData(JNIEnv *env) {
149 jclass clazz = env->FindClass(
150 "android/graphics/gpuprofiling/app/GpuRenderStagesDeviceActivity");
151 return env->RegisterNatives(clazz, gMethods,
152 sizeof(gMethods) / sizeof(JNINativeMethod));
153 }