184 lines
4.6 KiB
C++
184 lines
4.6 KiB
C++
/*
|
|
* 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
|