| /* |
| * Copyright (C) 2016 The Android Open Source Project |
| * |
| * 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 "rsovContext.h" |
| |
| #include <vector> |
| |
| #include "rsUtils.h" |
| |
| namespace android { |
| namespace renderscript { |
| namespace rsov { |
| |
| RSoVContext* RSoVContext::mContext = nullptr; |
| std::once_flag RSoVContext::mInitFlag; |
| |
| bool RSoVContext::Initialize(char const* const name) { |
| // Initialize instance |
| VkApplicationInfo appInfo = { |
| .sType = VK_STRUCTURE_TYPE_APPLICATION_INFO, |
| .pNext = nullptr, |
| .pApplicationName = name, // TODO: set to app name |
| .applicationVersion = 1, |
| .pEngineName = name, |
| .engineVersion = 1, |
| .apiVersion = VK_API_VERSION_1_0}; |
| |
| VkInstanceCreateInfo instInfo = { |
| .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, |
| .pNext = nullptr, |
| .flags = 0, |
| .pApplicationInfo = &appInfo, |
| }; |
| |
| VkResult res; |
| res = vkCreateInstance(&instInfo, nullptr, &mInstance); |
| if (res != VK_SUCCESS) { |
| return false; |
| } |
| |
| // Enumerate devices |
| uint32_t gpu_count; |
| |
| res = vkEnumeratePhysicalDevices(mInstance, &gpu_count, nullptr); |
| if (gpu_count == 0) { |
| return false; |
| } |
| |
| std::vector<VkPhysicalDevice> GPUs(gpu_count); |
| |
| res = vkEnumeratePhysicalDevices(mInstance, &gpu_count, GPUs.data()); |
| if (!(res == VK_SUCCESS && gpu_count > 0)) { |
| return false; |
| } |
| |
| mGPU = GPUs[0]; |
| |
| // Get device memory properties |
| vkGetPhysicalDeviceMemoryProperties(mGPU, &mMemoryProperties); |
| |
| // Initialize device |
| |
| float queuePriorities[] = {0.0}; |
| |
| VkDeviceQueueCreateInfo queueInfo = { |
| .sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, |
| .pNext = nullptr, |
| .queueCount = 1, |
| .pQueuePriorities = queuePriorities, |
| }; |
| |
| VkDeviceCreateInfo deviceInfo = { |
| .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, |
| .pNext = nullptr, |
| .queueCreateInfoCount = 1, |
| .pQueueCreateInfos = &queueInfo, |
| .pEnabledFeatures = nullptr, |
| }; |
| |
| res = vkCreateDevice(mGPU, &deviceInfo, nullptr, &mDevice); |
| if (res != VK_SUCCESS) { |
| return false; |
| } |
| |
| // Initialize queue family index |
| uint32_t queueCount; |
| |
| vkGetPhysicalDeviceQueueFamilyProperties(mGPU, &queueCount, nullptr); |
| if (queueCount == 0) { |
| return false; |
| } |
| |
| std::vector<VkQueueFamilyProperties> queueProps(queueCount); |
| |
| vkGetPhysicalDeviceQueueFamilyProperties(mGPU, &queueCount, |
| queueProps.data()); |
| if (queueCount == 0) { |
| return false; |
| } |
| |
| uint32_t queueFamilyIndex = UINT_MAX; |
| bool found = false; |
| for (unsigned int i = 0; i < queueCount; i++) { |
| if (queueProps[i].queueFlags & VK_QUEUE_COMPUTE_BIT) { |
| queueFamilyIndex = i; |
| found = true; |
| break; |
| } |
| } |
| |
| if (!found) { |
| return false; |
| } |
| |
| // Create a device queue |
| |
| vkGetDeviceQueue(mDevice, queueFamilyIndex, 0, &mQueue); |
| |
| // Create command pool |
| |
| VkCommandPoolCreateInfo cmd_pool_info = { |
| .sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, |
| .pNext = nullptr, |
| .queueFamilyIndex = queueFamilyIndex, |
| .flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, |
| }; |
| |
| res = vkCreateCommandPool(mDevice, &cmd_pool_info, nullptr, &mCmdPool); |
| if (res != VK_SUCCESS) { |
| return false; |
| } |
| |
| return true; |
| } |
| |
| bool RSoVContext::MemoryTypeFromProperties(uint32_t typeBits, |
| VkFlags requirements_mask, |
| uint32_t* typeIndex) { |
| for (uint32_t i = 0; i < 32; i++) { |
| if ((typeBits & 1) == 1) { |
| const uint32_t prop = mMemoryProperties.memoryTypes[i].propertyFlags; |
| if ((prop & requirements_mask) == requirements_mask) { |
| *typeIndex = i; |
| return true; |
| } |
| } |
| typeBits >>= 1; |
| } |
| |
| return false; |
| } |
| |
| RSoVContext::RSoVContext() {} |
| |
| RSoVContext::~RSoVContext() {} |
| |
| RSoVContext* RSoVContext::create() { |
| std::call_once(mInitFlag, []() { |
| std::unique_ptr<RSoVContext> context(new RSoVContext()); |
| char engineName[] = "RSoV"; |
| |
| if (context && context->Initialize(engineName)) { |
| mContext = context.release(); |
| } |
| }); |
| return mContext; |
| } |
| |
| } // namespace rsov |
| } // namespace renderscript |
| } // namespace android |