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 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 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 166 RSoVContext::RSoVContext() {} 167 168 RSoVContext::~RSoVContext() {} 169 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