1 /*
2 * Copyright (C) 2016 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 #include "rsovContext.h"
18
19 #include <vector>
20
21 #include "rsUtils.h"
22
23 namespace android {
24 namespace renderscript {
25 namespace rsov {
26
27 RSoVContext* RSoVContext::mContext = nullptr;
28 std::once_flag RSoVContext::mInitFlag;
29
Initialize(char const * const name)30 bool RSoVContext::Initialize(char const* const name) {
31 // Initialize instance
32 VkApplicationInfo appInfo = {
33 .sType = VK_STRUCTURE_TYPE_APPLICATION_INFO,
34 .pNext = nullptr,
35 .pApplicationName = name, // TODO: set to app name
36 .applicationVersion = 1,
37 .pEngineName = name,
38 .engineVersion = 1,
39 .apiVersion = VK_API_VERSION_1_0};
40
41 VkInstanceCreateInfo instInfo = {
42 .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
43 .pNext = nullptr,
44 .flags = 0,
45 .pApplicationInfo = &appInfo,
46 };
47
48 VkResult res;
49 res = vkCreateInstance(&instInfo, nullptr, &mInstance);
50 if (res != VK_SUCCESS) {
51 return false;
52 }
53
54 // Enumerate devices
55 uint32_t gpu_count;
56
57 res = vkEnumeratePhysicalDevices(mInstance, &gpu_count, nullptr);
58 if (gpu_count == 0) {
59 return false;
60 }
61
62 std::vector<VkPhysicalDevice> GPUs(gpu_count);
63
64 res = vkEnumeratePhysicalDevices(mInstance, &gpu_count, GPUs.data());
65 if (!(res == VK_SUCCESS && gpu_count > 0)) {
66 return false;
67 }
68
69 mGPU = GPUs[0];
70
71 // Get device memory properties
72 vkGetPhysicalDeviceMemoryProperties(mGPU, &mMemoryProperties);
73
74 // Initialize device
75
76 float queuePriorities[] = {0.0};
77
78 VkDeviceQueueCreateInfo queueInfo = {
79 .sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
80 .pNext = nullptr,
81 .queueCount = 1,
82 .pQueuePriorities = queuePriorities,
83 };
84
85 VkDeviceCreateInfo deviceInfo = {
86 .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
87 .pNext = nullptr,
88 .queueCreateInfoCount = 1,
89 .pQueueCreateInfos = &queueInfo,
90 .pEnabledFeatures = nullptr,
91 };
92
93 res = vkCreateDevice(mGPU, &deviceInfo, nullptr, &mDevice);
94 if (res != VK_SUCCESS) {
95 return false;
96 }
97
98 // Initialize queue family index
99 uint32_t queueCount;
100
101 vkGetPhysicalDeviceQueueFamilyProperties(mGPU, &queueCount, nullptr);
102 if (queueCount == 0) {
103 return false;
104 }
105
106 std::vector<VkQueueFamilyProperties> queueProps(queueCount);
107
108 vkGetPhysicalDeviceQueueFamilyProperties(mGPU, &queueCount,
109 queueProps.data());
110 if (queueCount == 0) {
111 return false;
112 }
113
114 uint32_t queueFamilyIndex = UINT_MAX;
115 bool found = false;
116 for (unsigned int i = 0; i < queueCount; i++) {
117 if (queueProps[i].queueFlags & VK_QUEUE_COMPUTE_BIT) {
118 queueFamilyIndex = i;
119 found = true;
120 break;
121 }
122 }
123
124 if (!found) {
125 return false;
126 }
127
128 // Create a device queue
129
130 vkGetDeviceQueue(mDevice, queueFamilyIndex, 0, &mQueue);
131
132 // Create command pool
133
134 VkCommandPoolCreateInfo cmd_pool_info = {
135 .sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
136 .pNext = nullptr,
137 .queueFamilyIndex = queueFamilyIndex,
138 .flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,
139 };
140
141 res = vkCreateCommandPool(mDevice, &cmd_pool_info, nullptr, &mCmdPool);
142 if (res != VK_SUCCESS) {
143 return false;
144 }
145
146 return true;
147 }
148
MemoryTypeFromProperties(uint32_t typeBits,VkFlags requirements_mask,uint32_t * typeIndex)149 bool RSoVContext::MemoryTypeFromProperties(uint32_t typeBits,
150 VkFlags requirements_mask,
151 uint32_t* typeIndex) {
152 for (uint32_t i = 0; i < 32; i++) {
153 if ((typeBits & 1) == 1) {
154 const uint32_t prop = mMemoryProperties.memoryTypes[i].propertyFlags;
155 if ((prop & requirements_mask) == requirements_mask) {
156 *typeIndex = i;
157 return true;
158 }
159 }
160 typeBits >>= 1;
161 }
162
163 return false;
164 }
165
RSoVContext()166 RSoVContext::RSoVContext() {}
167
~RSoVContext()168 RSoVContext::~RSoVContext() {}
169
create()170 RSoVContext* RSoVContext::create() {
171 std::call_once(mInitFlag, []() {
172 std::unique_ptr<RSoVContext> context(new RSoVContext());
173 char engineName[] = "RSoV";
174
175 if (context && context->Initialize(engineName)) {
176 mContext = context.release();
177 }
178 });
179 return mContext;
180 }
181
182 } // namespace rsov
183 } // namespace renderscript
184 } // namespace android
185