Updated example to start using core structure
This commit is contained in:
parent
0182836386
commit
6c41ceb0b2
15 changed files with 622 additions and 118 deletions
1
examples/android/android-simple/.gitignore
vendored
1
examples/android/android-simple/.gitignore
vendored
|
|
@ -9,4 +9,3 @@ local.properties
|
|||
.cxx
|
||||
.cdep
|
||||
cdep.sha256
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,14 @@
|
|||
Vulkan Kompute Android Example
|
||||
Tutorial 02 - use validation layers - 1
|
||||
===========
|
||||
Loading Vulkan to Andriod Application using Vulkan Kompute.
|
||||
1. Add validation layers into gradle and pack them into apk
|
||||
1. Enable all validation layers/extensions found on the system
|
||||
1. Use vulkan wrappers in common/vulkan_wrapper directory
|
||||
|
||||
Verification
|
||||
============
|
||||
Planted error: this sample sets `VkDeviceQueueCreateInfo::pQueuePriorities` to nullptr,
|
||||
which will trigger validation layers to notify us from registered callback function
|
||||
`vkDebugReportCallbackEX_impl();` putting a breakpoint with Android Studo, observe
|
||||
the breakpoint being triggered.
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,18 +1,23 @@
|
|||
apply plugin: 'com.android.application'
|
||||
|
||||
Properties properties = new Properties()
|
||||
properties.load(project.rootProject.file('local.properties').newDataInputStream())
|
||||
def ndkDir = properties.getProperty('ndk.dir')
|
||||
def valLayerBinDir = "${ndkDir}/sources/third_party/vulkan/src/build-android/jniLibs"
|
||||
|
||||
android {
|
||||
compileSdkVersion 24
|
||||
|
||||
defaultConfig {
|
||||
applicationId "com.kompute.examples.android"
|
||||
applicationId "com.ethicalml.kompute.examples.android"
|
||||
minSdkVersion 24
|
||||
targetSdkVersion 24
|
||||
versionCode 1
|
||||
versionName "0.0.1"
|
||||
versionCode = 1
|
||||
versionName = "0.0.1"
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
abiFilters "armeabi-v7a", 'arm64-v8a', 'x86', 'x86_64'
|
||||
arguments '-DANDROID_TOOLCHAIN=clang', '-DANDROID_STL=c++_static'
|
||||
arguments '-DANDROID_TOOLCHAIN=clang', '-DANDROID_STL=c++_static', '-DKOMPUTE_OPT_ANDOID_BUILD=1', '-DKOMPUTE_OPT_INSTALL=0'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -21,13 +26,22 @@ android {
|
|||
path 'src/main/jni/CMakeLists.txt'
|
||||
}
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled = false
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
|
||||
sourceSets {
|
||||
main {
|
||||
jniLibs {
|
||||
// Must have ndk-r12 or better which including layer binaries
|
||||
srcDirs = ["${valLayerBinDir}"]
|
||||
}
|
||||
}
|
||||
}
|
||||
ndkVersion '21.3.6528147'
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled = false
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# Add project specific ProGuard rules here.
|
||||
# By default, the flags in this file are appended to flags specified
|
||||
# in {ANDROID_SDK}/tools/proguard/proguard-android.txt
|
||||
# in ${ANDROID_SDK}/tools/proguard/proguard-android.txt
|
||||
# You can edit the include path and order by changing the proguardFiles
|
||||
# directive in build.gradle.
|
||||
#
|
||||
|
|
|
|||
|
|
@ -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" />
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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__
|
||||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ buildscript {
|
|||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:4.0.1'
|
||||
classpath 'com.android.tools.build:gradle:3.5.2'
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
// in the individual module build.gradle files
|
||||
}
|
||||
|
|
|
|||
12
examples/android/android-simple/gradle/wrapper/gradle-wrapper.properties
vendored
Executable file → Normal file
12
examples/android/android-simple/gradle/wrapper/gradle-wrapper.properties
vendored
Executable file → Normal file
|
|
@ -1,6 +1,6 @@
|
|||
#Tue Sep 29 20:22:44 BST 2020
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip
|
||||
#Mon Jan 13 14:51:34 PST 2020
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip
|
||||
|
|
|
|||
100
examples/android/android-simple/gradlew
vendored
100
examples/android/android-simple/gradlew
vendored
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env sh
|
||||
#!/usr/bin/env bash
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
|
|
@ -6,6 +6,42 @@
|
|||
##
|
||||
##############################################################################
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS=""
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn ( ) {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
die ( ) {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
esac
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
|
|
@ -24,46 +60,6 @@ cd "`dirname \"$PRG\"`/" >/dev/null
|
|||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >/dev/null
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS=""
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn () {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
NONSTOP* )
|
||||
nonstop=true
|
||||
;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
|
|
@ -89,7 +85,7 @@ location of your Java installation."
|
|||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
|
|
@ -154,19 +150,11 @@ if $cygwin ; then
|
|||
esac
|
||||
fi
|
||||
|
||||
# Escape application args
|
||||
save () {
|
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||
echo " "
|
||||
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
|
||||
function splitJvmOpts() {
|
||||
JVM_OPTS=("$@")
|
||||
}
|
||||
APP_ARGS=$(save "$@")
|
||||
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
|
||||
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
|
||||
|
||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||
|
||||
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
|
||||
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
|
||||
cd "$(dirname "$0")"
|
||||
fi
|
||||
|
||||
exec "$JAVACMD" "$@"
|
||||
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
|
||||
|
|
|
|||
14
examples/android/android-simple/gradlew.bat
vendored
14
examples/android/android-simple/gradlew.bat
vendored
|
|
@ -8,14 +8,14 @@
|
|||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS=
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS=
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
|
|
@ -46,9 +46,10 @@ echo location of your Java installation.
|
|||
goto fail
|
||||
|
||||
:init
|
||||
@rem Get command-line arguments, handling Windows variants
|
||||
@rem Get command-line arguments, handling Windowz variants
|
||||
|
||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||
if "%@eval[2+2]" == "4" goto 4NT_args
|
||||
|
||||
:win9xME_args
|
||||
@rem Slurp the command line arguments.
|
||||
|
|
@ -59,6 +60,11 @@ set _SKIP=2
|
|||
if "x%~1" == "x" goto execute
|
||||
|
||||
set CMD_LINE_ARGS=%*
|
||||
goto execute
|
||||
|
||||
:4NT_args
|
||||
@rem Get arguments from the 4NT Shell from JP Software
|
||||
set CMD_LINE_ARGS=%$
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
|
|
|||
|
|
@ -1 +1,2 @@
|
|||
include ':app'
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue