Updated example to start using core structure

This commit is contained in:
Alejandro Saucedo 2020-10-01 18:44:25 +01:00
parent 0182836386
commit 6c41ceb0b2
15 changed files with 622 additions and 118 deletions

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- BEGIN_INCLUDE(manifest) -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.google.vulkan.tutorial.one"
package="com.ethicalml.kompute.examples.android"
android:versionCode="1"
android:versionName="1.0">
@ -15,7 +15,7 @@
android:configChanges="orientation|keyboardHidden">
<!-- Tell NativeActivity the name of or .so -->
<meta-data android:name="android.app.lib_name"
android:value="vktuts" />
android:value="kompute_android" />
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />

View file

@ -1,16 +1,38 @@
cmake_minimum_required(VERSION 3.4.1)
add_subdirectory(../../../../../../../ ${CMAKE_CURRENT_BINARY_DIR}/kompute_build)
set(ANDROID_APP_GLUE_DIR ${ANDROID_NDK}/sources/android/native_app_glue)
set(VK_ANDROID_COMMON_DIR ${ANDROID_NDK}/sources/third_party/vulkan/src/common)
set(VK_ANDROID_INCLUDE_DIR ${ANDROID_NDK}/sources/third_party/vulkan/src/include)
# build native_app_glue as a static lib
set(APP_GLUE_DIR ${ANDROID_NDK}/sources/android/native_app_glue)
include_directories(${APP_GLUE_DIR})
add_library( app-glue STATIC ${APP_GLUE_DIR}/android_native_app_glue.c)
include_directories(${ANDROID_APP_GLUE_DIR})
add_library(app-glue STATIC
${ANDROID_APP_GLUE_DIR}/android_native_app_glue.c)
add_library(vktuts SHARED
# build vulkan app
add_library(kompute_android SHARED
TutorialValLayer.cpp
main.cpp
vulkan_wrapper.cpp)
${VK_ANDROID_COMMON_DIR}/vulkan_wrapper.cpp)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror -std=c++11 \
-DVK_USE_PLATFORM_ANDROID_KHR")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -u ANativeActivity_onCreate")
include_directories(
${VK_ANDROID_COMMON_DIR}
${VK_ANDROID_INCLUDE_DIR})
target_link_libraries(vktuts app-glue log android)
# TODO: Explore:
# * -DVK_NO_PROTOTYPES
# * -DUSE_DEBUG_EXTENTIONS
# * -Wno-unused-variable
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -Werror \
-DVK_USE_PLATFORM_ANDROID_KHR -DVK_NO_PROTOTYPES")
set(CMAKE_SHARED_LINKER_FLAGS
"${CMAKE_SHARED_LINKER_FLAGS} -u ANativeActivity_onCreate")
target_link_libraries(kompute_android
kompute
app-glue
log
android)

View file

@ -0,0 +1,361 @@
// Copyright 2016 Google Inc. All Rights Reserved.
//
// 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 "TutorialValLayer.hpp"
#include <android/log.h>
#include <cassert>
// Android log function wrappers
static const char* kTAG = "Vulkan-Tutorial02";
#define LOGI(...) \
((void)__android_log_print(ANDROID_LOG_INFO, kTAG, __VA_ARGS__))
#define LOGW(...) \
((void)__android_log_print(ANDROID_LOG_WARN, kTAG, __VA_ARGS__))
#define LOGE(...) \
((void)__android_log_print(ANDROID_LOG_ERROR, kTAG, __VA_ARGS__))
// Vulkan call wrapper
#define CALL_VK(func) \
if (VK_SUCCESS != (func)) { \
__android_log_print(ANDROID_LOG_ERROR, "Tutorial ", \
"Vulkan error. File[%s], line[%d]", __FILE__, \
__LINE__); \
assert(false); \
}
/*
* Validation Layer names at this time (info purpose)
static const char* kValLayerNames[] = {
"VK_LAYER_GOOGLE_threading",
"VK_LAYER_LUNARG_device_limits",
"VK_LAYER_LUNARG_core_validation",
"VK_LAYER_LUNARG_image",
"VK_LAYER_LUNARG_object_tracker",
"VK_LAYER_LUNARG_parameter_validation",
"VK_LAYER_LUNARG_swapchain",
"VK_LAYER_GOOGLE_unique_objects",
};
*/
static const char* kUniqueObjectLayer = "VK_LAYER_GOOGLE_unique_objects";
static const char* kGoogleThreadingLayer = "VK_LAYER_GOOGLE_threading";
// Debug Extension names in use.
// assumed usage:
// 1) app calls GetDbgExtName()
// 2) app calls IsExtSupported() to make sure it is supported
// 3) app tucks dbg extension name into InstanceCreateInfo to create instance
// 4) app calls CreateDbgExtCallback() to hook up debug print message
static const char* kDbgExtName = "VK_EXT_debug_report";
// Simple Dbg Callback function to be used by Vk engine
static VkBool32 VKAPI_PTR vkDebugReportCallbackEX_impl(
VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objectType,
uint64_t object, size_t location, int32_t messageCode,
const char* pLayerPrefix, const char* pMessage, void* pUserData) {
if (flags & VK_DEBUG_REPORT_INFORMATION_BIT_EXT) {
__android_log_print(ANDROID_LOG_INFO, "Vulkan-Debug-Message: ", "%s -- %s",
pLayerPrefix, pMessage);
}
if (flags & VK_DEBUG_REPORT_WARNING_BIT_EXT) {
__android_log_print(ANDROID_LOG_WARN, "Vulkan-Debug-Message: ", "%s -- %s",
pLayerPrefix, pMessage);
}
if (flags & VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT) {
__android_log_print(ANDROID_LOG_WARN, "Vulkan-Debug-Message-(Perf): ",
"%s -- %s", pLayerPrefix, pMessage);
}
if (flags & VK_DEBUG_REPORT_ERROR_BIT_EXT) {
__android_log_print(ANDROID_LOG_ERROR, "Vulkan-Debug-Message: ", "%s -- %s",
pLayerPrefix, pMessage);
}
if (flags & VK_DEBUG_REPORT_DEBUG_BIT_EXT) {
__android_log_print(ANDROID_LOG_DEBUG, "Vulkan-Debug-Message: ", "%s -- %s",
pLayerPrefix, pMessage);
}
return VK_FALSE;
}
// Reinforce the layer name sequence to meet load sequence
// requirement if there is any
void LayerAndExtensions::CheckLayerLoadingSequence(
std::vector<char*>* layerPtr) {
// VK_LAYER_GOOGLE_unique_objects need to be after
// VK_LAYER_LUNARG_core_validation
// VK_GOOGLE_THREADING_LAYER better to be the very first one
std::vector<char*>& layers = *layerPtr;
uint32_t uniqueObjIdx = -1;
uint32_t threadingIdx = -1;
uint32_t size = layers.size();
for (uint32_t idx = 0; idx < size; ++idx) {
if (!strcmp(layers[idx], kUniqueObjectLayer)) uniqueObjIdx = idx;
if (!strcmp(layers[idx], kGoogleThreadingLayer)) threadingIdx = idx;
}
if (uniqueObjIdx != -1) {
char* tmp = layers[uniqueObjIdx];
layers[uniqueObjIdx] = layers[size - 1];
layers[size - 1] = tmp;
}
if (threadingIdx != -1) {
char* tmp = layers[threadingIdx];
layers[threadingIdx] = layers[0];
layers[0] = tmp;
}
}
bool LayerAndExtensions::InitExtNames(const std::vector<ExtInfo>& prop,
std::vector<char*>* names) {
names->clear();
for (auto& ext : prop) {
for (uint32_t i = 0; i < ext.count; ++i) {
// skip the one already inside
bool duplicate = false;
for (uint32_t j = 0; j < names->size(); ++j) {
if (!strcmp(ext.prop[i].extensionName, (*names)[j])) {
duplicate = true;
break;
}
}
if (duplicate) continue;
// save this unique one
names->push_back(ext.prop[i].extensionName);
LOGI("Ext name: %s", ext.prop[i].extensionName);
}
}
return true;
}
bool LayerAndExtensions::InitInstExts(void) {
ExtInfo extInfo{0, nullptr};
CALL_VK(
vkEnumerateInstanceExtensionProperties(nullptr, &extInfo.count, nullptr));
if (extInfo.count) {
extInfo.prop = new VkExtensionProperties[extInfo.count];
assert(extInfo.prop);
CALL_VK(vkEnumerateInstanceExtensionProperties(nullptr, &extInfo.count,
extInfo.prop));
instExtProp_.push_back(extInfo);
}
for (int i = 0; i < instLayerCount_; i++) {
extInfo.count = 0;
CALL_VK(vkEnumerateInstanceExtensionProperties(instLayerProp_[i].layerName,
&extInfo.count, nullptr));
if (extInfo.count == 0) continue;
extInfo.prop = new VkExtensionProperties[extInfo.count];
CALL_VK(vkEnumerateInstanceExtensionProperties(
instLayerProp_[i].layerName, &extInfo.count, extInfo.prop));
instExtProp_.push_back(extInfo);
}
return InitExtNames(instExtProp_, &instExts_);
}
char** LayerAndExtensions::InstLayerNames(void) {
if (instLayers_.size()) {
return static_cast<char**>(instLayers_.data());
}
return nullptr;
}
uint32_t LayerAndExtensions::InstLayerCount(void) {
LOGI("InstLayerCount = %d", static_cast<int32_t>(instLayers_.size()));
return static_cast<int32_t>(instLayers_.size());
}
char** LayerAndExtensions::InstExtNames(void) {
if (instExts_.size()) {
return static_cast<char**>(instExts_.data());
}
return nullptr;
}
uint32_t LayerAndExtensions::InstExtCount(void) {
LOGI("InstExtCount: %d", static_cast<uint32_t>(instExts_.size()));
return static_cast<uint32_t>(instExts_.size());
}
bool LayerAndExtensions::IsInstExtSupported(const char* extName) {
for (auto name : instExts_) {
if (!strcmp(name, extName)) {
return true;
}
}
return false;
}
bool LayerAndExtensions::AddInstanceExt(const char* extName) {
if (!extName) return false;
// enable all available extensions, plus the one asked
if (!IsInstExtSupported(extName)) {
#ifdef ENABLE_NON_ENUMERATED_EXT
instExts.push_back(static_cast<char*>(extName));
instExtCount++;
return true;
#else
return false;
#endif
}
return true;
}
bool LayerAndExtensions::IsInstLayerSupported(const char* layerName) {
InstLayerNames();
for (auto name : instLayers_) {
if (!strcmp(name, layerName)) return true;
}
return false;
}
LayerAndExtensions::LayerAndExtensions(void) {
instance_ = VK_NULL_HANDLE;
vkCallbackHandle_ = VK_NULL_HANDLE;
CALL_VK(vkEnumerateInstanceLayerProperties(&instLayerCount_, nullptr));
if (instLayerCount_) {
instLayerProp_ = new VkLayerProperties[instLayerCount_];
assert(instLayerProp_);
CALL_VK(
vkEnumerateInstanceLayerProperties(&instLayerCount_, instLayerProp_));
}
for (uint32_t i = 0; i < instLayerCount_; i++) {
instLayers_.push_back(instLayerProp_[i].layerName);
LOGI("InstLayer name: %s", instLayerProp_[i].layerName);
}
CheckLayerLoadingSequence(&instLayers_);
InitInstExts();
}
LayerAndExtensions::~LayerAndExtensions() {
if (instLayerProp_) {
delete[] instLayerProp_;
}
for (auto ext : instExtProp_) {
delete[] ext.prop;
}
if (vkCallbackHandle_) {
vkDestroyDebugReportCallbackEXT(instance_, vkCallbackHandle_, nullptr);
}
}
void LayerAndExtensions::InitDevLayersAndExt(VkPhysicalDevice physicalDevice) {
physicalDev_ = physicalDevice;
if (physicalDev_ == VK_NULL_HANDLE) return;
// get all supported layers props
devLayerCount_ = 0;
CALL_VK(
vkEnumerateDeviceLayerProperties(physicalDev_, &devLayerCount_, nullptr));
if (devLayerCount_) {
devLayerProp_ = new VkLayerProperties[devLayerCount_];
assert(devLayerProp_);
CALL_VK(vkEnumerateDeviceLayerProperties(physicalDev_, &devLayerCount_,
devLayerProp_));
}
#ifdef LOADER_DEVICE_LAYER_REPORT_BUG_WA
// validation layer for device only report out for one layer,
// but it seems we could ask for all layers that asked for instance
// so we just add them all in brutally
// assume all device layers are also implemented for device layers
if (devLayerCount_ == 1) {
LOGI("Only Reported One layer for device");
if (devLayerProp_) delete[] devLayerProp_;
devLayerProp_ =
(instLayerCount_ ? (new VkLayerProperties[instLayerCount_]) : nullptr);
memcpy(devLayerProp_, instLayerProp_,
instLayerCount_ * sizeof(VkLayerProperties));
devLayerCount_ = instLayerCount_;
}
#endif
for (int i = 0; i < devLayerCount_; i++) {
LOGI("deviceLayerName: %s", devLayerProp_[i].layerName);
devLayers_.push_back(devLayerProp_[i].layerName);
}
CheckLayerLoadingSequence(&devLayers_);
// get all supported ext props
ExtInfo ext{0, nullptr};
CALL_VK(vkEnumerateDeviceExtensionProperties(physicalDev_, nullptr,
&ext.count, nullptr));
if (ext.count) {
ext.prop = new VkExtensionProperties[ext.count];
assert(ext.prop);
CALL_VK(vkEnumerateDeviceExtensionProperties(physicalDev_, nullptr,
&ext.count, ext.prop));
devExtProp_.push_back(ext);
}
for (int i = 0; i < devLayerCount_; i++) {
ext.count = 0;
CALL_VK(vkEnumerateDeviceExtensionProperties(
physicalDev_, devLayerProp_[i].layerName, &ext.count, nullptr));
if (ext.count) {
ext.prop = new VkExtensionProperties[ext.count];
assert(ext.prop);
CALL_VK(vkEnumerateDeviceExtensionProperties(
physicalDev_, devLayerProp_[i].layerName, &ext.count, ext.prop));
devExtProp_.push_back(ext);
}
}
InitExtNames(devExtProp_, &devExts_);
}
char** LayerAndExtensions::DevLayerNames(void) {
assert(physicalDev_ != VK_NULL_HANDLE);
if (devLayers_.size()) return devLayers_.data();
return nullptr;
}
uint32_t LayerAndExtensions::DevLayerCount(void) {
assert(physicalDev_ != VK_NULL_HANDLE);
return devLayers_.size();
}
char** LayerAndExtensions::DevExtNames(void) {
assert(physicalDev_ != VK_NULL_HANDLE);
if (devExts_.size()) return devExts_.data();
return nullptr;
}
uint32_t LayerAndExtensions::DevExtCount(void) {
assert(physicalDev_ != VK_NULL_HANDLE);
return devExts_.size();
}
const char* LayerAndExtensions::GetDbgExtName(void) { return kDbgExtName; }
bool LayerAndExtensions::HookDbgReportExt(VkInstance instance) {
instance_ = instance;
if (!IsInstExtSupported(GetDbgExtName())) {
return false;
}
if (!vkCreateDebugReportCallbackEXT) {
vkCreateDebugReportCallbackEXT =
(PFN_vkCreateDebugReportCallbackEXT)vkGetInstanceProcAddr(
instance, "vkCreateDebugReportCallbackEXT");
vkDestroyDebugReportCallbackEXT =
(PFN_vkDestroyDebugReportCallbackEXT)vkGetInstanceProcAddr(
instance, "vkDestroyDebugReportCallbackEXT");
vkDebugReportMessageEXT =
(PFN_vkDebugReportMessageEXT)vkGetInstanceProcAddr(
instance, "vkDebugReportMessageEXT");
}
VkDebugReportCallbackCreateInfoEXT dbgInfo = {
.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT,
.pNext = nullptr,
.flags = VK_DEBUG_REPORT_WARNING_BIT_EXT |
VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT |
VK_DEBUG_REPORT_ERROR_BIT_EXT,
.pfnCallback = vkDebugReportCallbackEX_impl,
.pUserData = this, // we provide the debug object as context
};
CALL_VK(vkCreateDebugReportCallbackEXT(instance, &dbgInfo, nullptr,
&vkCallbackHandle_));
return true;
}

View file

@ -0,0 +1,93 @@
// Copyright 2016 Google Inc. All Rights Reserved.
//
// 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.
#ifndef __VALLAYER_HPP__
#define __VALLAYER_HPP__
#include <vulkan_wrapper.h>
#include <iostream>
#include <map>
#include <vector>
// Some loader only report one layer for device layers, enable this to
// workaround it: it will copy all instance layers into device layers
// and NOT enumerating device layers
//#define LOADER_DEVICE_LAYER_REPORT_BUG_WA
// If extension is not enumerated, it should not be enabled in general;
// If you know an extension is on the device, but loader does not report it,
// it could be forced in by enabling
// the following compile flag and call AddInstanceExt().
// #define ENABLE_NON_ENUMERATED_EXT 1
// A Helper class to manage validation layers and extensions
// Supposed usage:
// 1) validation layers: app should enable them with
// InstanceLayerCount()
// InstanceLayerNames()
// 2) Extension layers: app should check for supportability
// and then enable in app code ( not in this class )
// 3) DbgExtension: once instance is created, just call
// HookDbgReportExt
class LayerAndExtensions {
public:
LayerAndExtensions(void);
~LayerAndExtensions();
uint32_t InstLayerCount(void);
char** InstLayerNames(void);
uint32_t InstExtCount(void);
char** InstExtNames(void);
bool IsInstExtSupported(const char* extName);
bool IsInstLayerSupported(const char* layerName);
const char* GetDbgExtName(void);
bool AddInstanceExt(const char* extName);
bool HookDbgReportExt(VkInstance instance);
void InitDevLayersAndExt(VkPhysicalDevice physicalDevice);
char** DevLayerNames(void);
uint32_t DevLayerCount(void);
char** DevExtNames(void);
uint32_t DevExtCount(void);
private:
// internal helper data structure
struct ExtInfo {
uint32_t count;
VkExtensionProperties* prop;
};
VkInstance instance_;
VkDebugReportCallbackEXT vkCallbackHandle_;
VkPhysicalDevice physicalDev_;
std::vector<char*> instLayers_;
std::vector<char*> instExts_;
std::vector<char*> devLayers_;
std::vector<char*> devExts_;
VkLayerProperties* instLayerProp_{nullptr};
uint32_t instLayerCount_{0};
std::vector<ExtInfo> instExtProp_;
VkLayerProperties* devLayerProp_{nullptr};
uint32_t devLayerCount_{0};
std::vector<ExtInfo> devExtProp_;
bool InitInstExts(void);
bool InitExtNames(const std::vector<ExtInfo>& props,
std::vector<char*>* names);
void CheckLayerLoadingSequence(std::vector<char*>* layers);
};
#endif // __VALLAYER_HPP__

View file

@ -16,10 +16,11 @@
#include <android_native_app_glue.h>
#include <cassert>
#include <vector>
#include "TutorialValLayer.hpp"
#include "vulkan_wrapper.h"
// Android log function wrappers
static const char* kTAG = "Vulkan-Tutorial01";
static const char* kTAG = "Vulkan-Tutorial02";
#define LOGI(...) \
((void)__android_log_print(ANDROID_LOG_INFO, kTAG, __VA_ARGS__))
#define LOGW(...) \
@ -79,36 +80,31 @@ bool initialize(android_app* app) {
.apiVersion = VK_MAKE_VERSION(1, 0, 0),
.applicationVersion = VK_MAKE_VERSION(1, 0, 0),
.engineVersion = VK_MAKE_VERSION(1, 0, 0),
.pApplicationName = "tutorial01_load_vulkan",
.pApplicationName = "tutorial02_prebuilt_layers",
.pEngineName = "tutorial",
};
// prepare necessary extensions: Vulkan on Android need these to function
std::vector<const char *> instanceExt, deviceExt;
instanceExt.push_back("VK_KHR_surface");
instanceExt.push_back("VK_KHR_android_surface");
deviceExt.push_back("VK_KHR_swapchain");
// prepare debug and layer objects
LayerAndExtensions layerAndExt;
layerAndExt.AddInstanceExt(layerAndExt.GetDbgExtName());
// Create the Vulkan instance
// Create Vulkan instance, requesting all enabled layers / extensions
// available on the system
VkInstanceCreateInfo instanceCreateInfo{
.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
.pNext = nullptr,
.pApplicationInfo = &appInfo,
.enabledExtensionCount = static_cast<uint32_t>(instanceExt.size()),
.ppEnabledExtensionNames = instanceExt.data(),
.enabledLayerCount = 0,
.ppEnabledLayerNames = nullptr,
.enabledExtensionCount = layerAndExt.InstExtCount(),
.ppEnabledExtensionNames =
static_cast<const char* const*>(layerAndExt.InstExtNames()),
.enabledLayerCount = layerAndExt.InstLayerCount(),
.ppEnabledLayerNames =
static_cast<const char* const*>(layerAndExt.InstLayerNames()),
};
CALL_VK(vkCreateInstance(&instanceCreateInfo, nullptr, &tutorialInstance));
// if we create a surface, we need the surface extension
VkAndroidSurfaceCreateInfoKHR createInfo{
.sType = VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR,
.pNext = nullptr,
.flags = 0,
.window = app->window};
CALL_VK(vkCreateAndroidSurfaceKHR(tutorialInstance, &createInfo, nullptr,
&tutorialSurface));
// Create debug callback obj and connect to vulkan instance
layerAndExt.HookDbgReportExt(tutorialInstance);
// Find one GPU to use:
// On Android, every GPU device is equal -- supporting
@ -120,6 +116,9 @@ bool initialize(android_app* app) {
CALL_VK(vkEnumeratePhysicalDevices(tutorialInstance, &gpuCount, tmpGpus));
tutorialGpu = tmpGpus[0]; // Pick up the first GPU Device
// Enumerate available device validation layers & extensions
layerAndExt.InitDevLayersAndExt(tutorialGpu);
// check for vulkan info on this GPU device
VkPhysicalDeviceProperties gpuProperties;
vkGetPhysicalDeviceProperties(tutorialGpu, &gpuProperties);
@ -131,6 +130,14 @@ bool initialize(android_app* app) {
VK_VERSION_MINOR(gpuProperties.apiVersion),
VK_VERSION_PATCH(gpuProperties.apiVersion));
VkAndroidSurfaceCreateInfoKHR createInfo{
.sType = VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR,
.pNext = nullptr,
.flags = 0,
.window = app->window};
CALL_VK(vkCreateAndroidSurfaceKHR(tutorialInstance, &createInfo, nullptr,
&tutorialSurface));
VkSurfaceCapabilitiesKHR surfaceCapabilities;
vkGetPhysicalDeviceSurfaceCapabilitiesKHR(tutorialGpu, tutorialSurface,
&surfaceCapabilities);
@ -178,7 +185,9 @@ bool initialize(android_app* app) {
.flags = 0,
.queueCount = 1,
.queueFamilyIndex = queueFamilyIndex,
.pQueuePriorities = priorities,
// Send nullptr for queue priority so debug extension could
// catch the bug and call back app's debug function
.pQueuePriorities = nullptr, // priorities,
};
VkDeviceCreateInfo deviceCreateInfo{
@ -186,17 +195,19 @@ bool initialize(android_app* app) {
.pNext = nullptr,
.queueCreateInfoCount = 1,
.pQueueCreateInfos = &queueCreateInfo,
.enabledLayerCount = 0,
.ppEnabledLayerNames = nullptr,
.enabledExtensionCount = static_cast<uint32_t>(deviceExt.size()),
.ppEnabledExtensionNames = deviceExt.data(),
.enabledLayerCount = layerAndExt.DevLayerCount(),
.ppEnabledLayerNames =
static_cast<const char* const*>(layerAndExt.DevLayerNames()),
.enabledExtensionCount = layerAndExt.DevExtCount(),
.ppEnabledExtensionNames =
static_cast<const char* const*>(layerAndExt.DevExtNames()),
.pEnabledFeatures = nullptr,
};
CALL_VK(
vkCreateDevice(tutorialGpu, &deviceCreateInfo, nullptr, &tutorialDevice));
initialized_ = true;
return 0;
return true;
}
void terminate(void) {

View file

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Tutorial 01</string>
<string name="app_name">Kompute Android Example</string>
</resources>