Android fixes and build files for headless compute example

This commit is contained in:
saschawillems 2017-09-15 20:44:32 +02:00
parent 3862b4bcc2
commit bc8b53ce7b
7 changed files with 156 additions and 21 deletions

View file

@ -7,6 +7,7 @@ EXAMPLES = [
"bloom",
"computecullandlod",
"computecloth",
"computeheadless",
"computenbody",
"computeparticles",
"computeshader",

10
android/computeheadless/.gitignore vendored Normal file
View file

@ -0,0 +1,10 @@
/assets/
/res/
/bin/
/libs/
/obj/
/build.xml
/local.properties
/project.properties
/proguard-project.txt
*.apk

View file

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="de.saschawillems.vulkanComputeheadless"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="19" />
<uses-feature android:name="android.hardware.touchscreen" android:required="false"/>
<uses-feature android:name="android.hardware.gamepad" android:required="false"/>
<uses-feature android:name="android.software.leanback" android:required="false"/>
<application android:label="vulkanComputeheadless" android:icon="@drawable/icon" android:hasCode="false">
<activity android:name="android.app.NativeActivity"
android:label="Headless compute"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
android:launchMode="singleTask"
android:configChanges="orientation|screenSize|keyboardHidden">
<meta-data android:name="android.app.lib_name" android:value="vulkanComputeheadless" />
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.LEANBACK_LAUNCHER"/>
</intent-filter>
</activity>
</application>
</manifest>

View file

@ -0,0 +1,8 @@
{
"apkname": "vulkanComputeheadless",
"directories": {
"shaders": "computeheadless"
},
"assets": {
}
}

View file

@ -0,0 +1,36 @@
LOCAL_PATH := $(call my-dir)/../../computeheadless
# vulkan example
DATADIR := $(LOCAL_PATH)/../../data
include $(CLEAR_VARS)
LOCAL_MODULE := vulkanComputeheadless
PROJECT_FILES := $(wildcard $(LOCAL_PATH)/../../computeheadless/*.cpp)
PROJECT_FILES += $(wildcard $(LOCAL_PATH)/../../base/VulkanTools.cpp)
PROJECT_FILES += $(wildcard $(LOCAL_PATH)/../../base/VulkanAndroid.cpp)
LOCAL_CPPFLAGS := -std=c++11
LOCAL_CPPFLAGS += -D__STDC_LIMIT_MACROS
LOCAL_CPPFLAGS += -DVK_NO_PROTOTYPES
LOCAL_CPPFLAGS += -DVK_USE_PLATFORM_ANDROID_KHR
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../external/
LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../base/
LOCAL_SRC_FILES := $(PROJECT_FILES)
LOCAL_LDLIBS := -landroid -llog -lz
LOCAL_DISABLE_FORMAT_STRING_CHECKS := true
LOCAL_DISABLE_FATAL_LINKER_WARNINGS := true
LOCAL_STATIC_LIBRARIES += android_native_app_glue
LOCAL_STATIC_LIBRARIES += cpufeatures
include $(BUILD_SHARED_LIBRARY)
$(call import-module, android/native_app_glue)
$(call import-module, android/cpufeatures)

View file

@ -0,0 +1,5 @@
APP_PLATFORM := android-19
APP_ABI := armeabi-v7a
APP_STL := c++_static
APP_CPPFLAGS := -std=c++11
NDK_TOOLCHAIN_VERSION := clang

View file

@ -10,6 +10,12 @@
#if defined(_WIN32)
#pragma comment(linker, "/subsystem:console")
#elif defined(VK_USE_PLATFORM_ANDROID_KHR)
#include <android/native_activity.h>
#include <android/asset_manager.h>
#include <android_native_app_glue.h>
#include <android/log.h>
#include "VulkanAndroid.h"
#endif
#include <stdio.h>
@ -23,10 +29,20 @@
#include <vulkan/vulkan.h>
#include "VulkanTools.h"
#if defined(VK_USE_PLATFORM_ANDROID_KHR)
android_app* androidapp;
#endif
#define DEBUG (!NDEBUG)
#define BUFFER_ELEMENTS 32
#if defined(VK_USE_PLATFORM_ANDROID_KHR)
#define LOG(...) ((void)__android_log_print(ANDROID_LOG_INFO, "vulkanExample", __VA_ARGS__))
#else
#define LOG(...) printf(__VA_ARGS__)
#endif
static VKAPI_ATTR VkBool32 VKAPI_CALL debugMessageCallback(
VkDebugReportFlagsEXT flags,
VkDebugReportObjectTypeEXT objectType,
@ -37,7 +53,7 @@ static VKAPI_ATTR VkBool32 VKAPI_CALL debugMessageCallback(
const char* pMessage,
void* pUserData)
{
std::cout << "[VALIDATION]:" << pLayerPrefix << ":" << pMessage << std::endl;
LOG("[VALIDATION]: %s - %s\n", pLayerPrefix, pMessage);
return VK_FALSE;
}
@ -103,7 +119,12 @@ public:
VulkanExample()
{
std::cout << "Running headless example" << std::endl;
LOG("Running headless compute example\n");
#if defined(VK_USE_PLATFORM_ANDROID_KHR)
LOG("loading vulkan lib");
vks::android::loadVulkanLibrary();
#endif
VkApplicationInfo appInfo = {};
appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
@ -117,22 +138,32 @@ public:
VkInstanceCreateInfo instanceCreateInfo = {};
instanceCreateInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
instanceCreateInfo.pApplicationInfo = &appInfo;
#if defined(DEBUG)
// TODO: Explicit layer names on Android
uint32_t layerCount = 0;
#if defined(VK_USE_PLATFORM_ANDROID_KHR)
const char* validationlayers[] = { "VK_LAYER_GOOGLE_threading", "VK_LAYER_LUNARG_parameter_validation", "VK_LAYER_LUNARG_object_tracker","VK_LAYER_LUNARG_core_validation", "VK_LAYER_LUNARG_swapchain", "VK_LAYER_GOOGLE_unique_objects" };
layerCount = 6;
#else
const char* validationlayers[] = { "VK_LAYER_LUNARG_standard_validation" };
const char* validationExt = VK_EXT_DEBUG_REPORT_EXTENSION_NAME;
instanceCreateInfo.enabledLayerCount = 1;
layerCount = 1;
#endif
#if DEBUG
instanceCreateInfo.ppEnabledLayerNames = validationlayers;
const char* validationExt = VK_EXT_DEBUG_REPORT_EXTENSION_NAME;
instanceCreateInfo.enabledLayerCount = layerCount;
instanceCreateInfo.enabledExtensionCount = 1;
instanceCreateInfo.ppEnabledExtensionNames = &validationExt;
#endif
VK_CHECK_RESULT(vkCreateInstance(&instanceCreateInfo, nullptr, &instance));
#if defined(DEBUG)
#if defined(VK_USE_PLATFORM_ANDROID_KHR)
vks::android::loadVulkanFunctions(instance);
#endif
#if DEBUG
VkDebugReportCallbackCreateInfoEXT debugReportCreateInfo = {};
debugReportCreateInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT;
debugReportCreateInfo.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT;
debugReportCreateInfo.pfnCallback = &debugMessageCallback;
debugReportCreateInfo.pfnCallback = (PFN_vkDebugReportCallbackEXT)debugMessageCallback;
// We have to explicitly load this function.
PFN_vkCreateDebugReportCallbackEXT vkCreateDebugReportCallbackEXT = reinterpret_cast<PFN_vkCreateDebugReportCallbackEXT>(vkGetInstanceProcAddr(instance, "vkCreateDebugReportCallbackEXT"));
@ -150,6 +181,10 @@ public:
VK_CHECK_RESULT(vkEnumeratePhysicalDevices(instance, &deviceCount, physicalDevices.data()));
physicalDevice = physicalDevices[0];
VkPhysicalDeviceProperties deviceProperties;
vkGetPhysicalDeviceProperties(physicalDevice, &deviceProperties);
LOG("GPU: %s\n", deviceProperties.deviceName);
// Request a single compute queue
const float defaultQueuePriority(0.0f);
VkDeviceQueueCreateInfo queueCreateInfo = {};
@ -297,7 +332,7 @@ public:
shaderStage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
shaderStage.stage = VK_SHADER_STAGE_COMPUTE_BIT;
#if defined(VK_USE_PLATFORM_ANDROID_KHR)
shaderStage.module = vks::tools::loadShader(androidApp->activity->assetManager, fileName.c_str(), device);
shaderStage.module = vks::tools::loadShader(androidapp->activity->assetManager, ASSET_PATH "shaders/computeheadless/headless.comp.spv", device);
#else
shaderStage.module = vks::tools::loadShader(ASSET_PATH "shaders/computeheadless/headless.comp.spv", device);
#endif
@ -415,15 +450,15 @@ public:
vkQueueWaitIdle(queue);
// Output buffer contents
std::cout << "Compute input: " << std::endl;
LOG("Compute input:\n");
for (auto v : computeInput) {
std::cout << v << "\t";
LOG("%d \t", v);
}
std::cout << std::endl;
std::cout << "Compute output: " << std::endl;
LOG("Compute output:\n");
for (auto v : computeOutput) {
std::cout << v << "\t";
LOG("%d \t", v);
}
std::cout << std::endl;
@ -433,7 +468,7 @@ public:
vkDestroyBuffer(device, hostBuffer, nullptr);
vkFreeMemory(device, hostMemory, nullptr);
#if defined(DEBUG)
#if DEBUG
PFN_vkDestroyDebugReportCallbackEXT vkDestroyDebugReportCallback = reinterpret_cast<PFN_vkDestroyDebugReportCallbackEXT>(vkGetInstanceProcAddr(instance, "vkDestroyDebugReportCallbackEXT"));
assert(vkDestroyDebugReportCallback);
vkDestroyDebugReportCallback(instance, debugReportCallback, nullptr);
@ -451,15 +486,28 @@ public:
}
};
#if defined(__ANDROID__)
// Android entry point
// A note on app_dummy(): This is required as the compiler may otherwise remove the main entry point of the application
VulkanExample *vulkanExample;
#if defined(VK_USE_PLATFORM_ANDROID_KHR)
void handleAppCommand(android_app * app, int32_t cmd) {
if (cmd == APP_CMD_INIT_WINDOW) {
VulkanExample *vulkanExample = new VulkanExample();
delete(vulkanExample);
ANativeActivity_finish(app->activity);
}
}
void android_main(android_app* state) {
app_dummy();
VulkanExample *vulkanExample = new VulkanExample();
state->userData = vulkanExample;
delete(vulkanExample);
androidapp = state;
androidapp->onAppCmd = handleAppCommand;
int ident, events;
struct android_poll_source* source;
while ((ident = ALooper_pollAll(-1, NULL, &events, (void**)&source)) >= 0) {
if (source != NULL) {
source->process(androidapp, source);
}
if (androidapp->destroyRequested != 0) {
break;
}
}
}
#else
int main() {