Android fixes and build files for headless compute example
This commit is contained in:
parent
3862b4bcc2
commit
bc8b53ce7b
7 changed files with 156 additions and 21 deletions
|
|
@ -7,6 +7,7 @@ EXAMPLES = [
|
||||||
"bloom",
|
"bloom",
|
||||||
"computecullandlod",
|
"computecullandlod",
|
||||||
"computecloth",
|
"computecloth",
|
||||||
|
"computeheadless",
|
||||||
"computenbody",
|
"computenbody",
|
||||||
"computeparticles",
|
"computeparticles",
|
||||||
"computeshader",
|
"computeshader",
|
||||||
|
|
|
||||||
10
android/computeheadless/.gitignore
vendored
Normal file
10
android/computeheadless/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
/assets/
|
||||||
|
/res/
|
||||||
|
/bin/
|
||||||
|
/libs/
|
||||||
|
/obj/
|
||||||
|
/build.xml
|
||||||
|
/local.properties
|
||||||
|
/project.properties
|
||||||
|
/proguard-project.txt
|
||||||
|
*.apk
|
||||||
27
android/computeheadless/AndroidManifest.xml
Normal file
27
android/computeheadless/AndroidManifest.xml
Normal 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>
|
||||||
8
android/computeheadless/example.json
Normal file
8
android/computeheadless/example.json
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
{
|
||||||
|
"apkname": "vulkanComputeheadless",
|
||||||
|
"directories": {
|
||||||
|
"shaders": "computeheadless"
|
||||||
|
},
|
||||||
|
"assets": {
|
||||||
|
}
|
||||||
|
}
|
||||||
36
android/computeheadless/jni/Android.mk
Normal file
36
android/computeheadless/jni/Android.mk
Normal 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)
|
||||||
5
android/computeheadless/jni/Application.mk
Normal file
5
android/computeheadless/jni/Application.mk
Normal 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
|
||||||
|
|
@ -10,6 +10,12 @@
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
#pragma comment(linker, "/subsystem:console")
|
#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
|
#endif
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
@ -23,10 +29,20 @@
|
||||||
#include <vulkan/vulkan.h>
|
#include <vulkan/vulkan.h>
|
||||||
#include "VulkanTools.h"
|
#include "VulkanTools.h"
|
||||||
|
|
||||||
|
#if defined(VK_USE_PLATFORM_ANDROID_KHR)
|
||||||
|
android_app* androidapp;
|
||||||
|
#endif
|
||||||
|
|
||||||
#define DEBUG (!NDEBUG)
|
#define DEBUG (!NDEBUG)
|
||||||
|
|
||||||
#define BUFFER_ELEMENTS 32
|
#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(
|
static VKAPI_ATTR VkBool32 VKAPI_CALL debugMessageCallback(
|
||||||
VkDebugReportFlagsEXT flags,
|
VkDebugReportFlagsEXT flags,
|
||||||
VkDebugReportObjectTypeEXT objectType,
|
VkDebugReportObjectTypeEXT objectType,
|
||||||
|
|
@ -37,7 +53,7 @@ static VKAPI_ATTR VkBool32 VKAPI_CALL debugMessageCallback(
|
||||||
const char* pMessage,
|
const char* pMessage,
|
||||||
void* pUserData)
|
void* pUserData)
|
||||||
{
|
{
|
||||||
std::cout << "[VALIDATION]:" << pLayerPrefix << ":" << pMessage << std::endl;
|
LOG("[VALIDATION]: %s - %s\n", pLayerPrefix, pMessage);
|
||||||
return VK_FALSE;
|
return VK_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -103,7 +119,12 @@ public:
|
||||||
|
|
||||||
VulkanExample()
|
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 = {};
|
VkApplicationInfo appInfo = {};
|
||||||
appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
|
appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
|
||||||
|
|
@ -117,22 +138,32 @@ public:
|
||||||
VkInstanceCreateInfo instanceCreateInfo = {};
|
VkInstanceCreateInfo instanceCreateInfo = {};
|
||||||
instanceCreateInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
|
instanceCreateInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
|
||||||
instanceCreateInfo.pApplicationInfo = &appInfo;
|
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* validationlayers[] = { "VK_LAYER_LUNARG_standard_validation" };
|
||||||
const char* validationExt = VK_EXT_DEBUG_REPORT_EXTENSION_NAME;
|
layerCount = 1;
|
||||||
instanceCreateInfo.enabledLayerCount = 1;
|
#endif
|
||||||
|
#if DEBUG
|
||||||
instanceCreateInfo.ppEnabledLayerNames = validationlayers;
|
instanceCreateInfo.ppEnabledLayerNames = validationlayers;
|
||||||
|
const char* validationExt = VK_EXT_DEBUG_REPORT_EXTENSION_NAME;
|
||||||
|
instanceCreateInfo.enabledLayerCount = layerCount;
|
||||||
instanceCreateInfo.enabledExtensionCount = 1;
|
instanceCreateInfo.enabledExtensionCount = 1;
|
||||||
instanceCreateInfo.ppEnabledExtensionNames = &validationExt;
|
instanceCreateInfo.ppEnabledExtensionNames = &validationExt;
|
||||||
#endif
|
#endif
|
||||||
VK_CHECK_RESULT(vkCreateInstance(&instanceCreateInfo, nullptr, &instance));
|
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 = {};
|
VkDebugReportCallbackCreateInfoEXT debugReportCreateInfo = {};
|
||||||
debugReportCreateInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT;
|
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.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.
|
// We have to explicitly load this function.
|
||||||
PFN_vkCreateDebugReportCallbackEXT vkCreateDebugReportCallbackEXT = reinterpret_cast<PFN_vkCreateDebugReportCallbackEXT>(vkGetInstanceProcAddr(instance, "vkCreateDebugReportCallbackEXT"));
|
PFN_vkCreateDebugReportCallbackEXT vkCreateDebugReportCallbackEXT = reinterpret_cast<PFN_vkCreateDebugReportCallbackEXT>(vkGetInstanceProcAddr(instance, "vkCreateDebugReportCallbackEXT"));
|
||||||
|
|
@ -150,6 +181,10 @@ public:
|
||||||
VK_CHECK_RESULT(vkEnumeratePhysicalDevices(instance, &deviceCount, physicalDevices.data()));
|
VK_CHECK_RESULT(vkEnumeratePhysicalDevices(instance, &deviceCount, physicalDevices.data()));
|
||||||
physicalDevice = physicalDevices[0];
|
physicalDevice = physicalDevices[0];
|
||||||
|
|
||||||
|
VkPhysicalDeviceProperties deviceProperties;
|
||||||
|
vkGetPhysicalDeviceProperties(physicalDevice, &deviceProperties);
|
||||||
|
LOG("GPU: %s\n", deviceProperties.deviceName);
|
||||||
|
|
||||||
// Request a single compute queue
|
// Request a single compute queue
|
||||||
const float defaultQueuePriority(0.0f);
|
const float defaultQueuePriority(0.0f);
|
||||||
VkDeviceQueueCreateInfo queueCreateInfo = {};
|
VkDeviceQueueCreateInfo queueCreateInfo = {};
|
||||||
|
|
@ -297,7 +332,7 @@ public:
|
||||||
shaderStage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
|
shaderStage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
|
||||||
shaderStage.stage = VK_SHADER_STAGE_COMPUTE_BIT;
|
shaderStage.stage = VK_SHADER_STAGE_COMPUTE_BIT;
|
||||||
#if defined(VK_USE_PLATFORM_ANDROID_KHR)
|
#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
|
#else
|
||||||
shaderStage.module = vks::tools::loadShader(ASSET_PATH "shaders/computeheadless/headless.comp.spv", device);
|
shaderStage.module = vks::tools::loadShader(ASSET_PATH "shaders/computeheadless/headless.comp.spv", device);
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -415,15 +450,15 @@ public:
|
||||||
vkQueueWaitIdle(queue);
|
vkQueueWaitIdle(queue);
|
||||||
|
|
||||||
// Output buffer contents
|
// Output buffer contents
|
||||||
std::cout << "Compute input: " << std::endl;
|
LOG("Compute input:\n");
|
||||||
for (auto v : computeInput) {
|
for (auto v : computeInput) {
|
||||||
std::cout << v << "\t";
|
LOG("%d \t", v);
|
||||||
}
|
}
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
|
|
||||||
std::cout << "Compute output: " << std::endl;
|
LOG("Compute output:\n");
|
||||||
for (auto v : computeOutput) {
|
for (auto v : computeOutput) {
|
||||||
std::cout << v << "\t";
|
LOG("%d \t", v);
|
||||||
}
|
}
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
|
|
||||||
|
|
@ -433,7 +468,7 @@ public:
|
||||||
vkDestroyBuffer(device, hostBuffer, nullptr);
|
vkDestroyBuffer(device, hostBuffer, nullptr);
|
||||||
vkFreeMemory(device, hostMemory, nullptr);
|
vkFreeMemory(device, hostMemory, nullptr);
|
||||||
|
|
||||||
#if defined(DEBUG)
|
#if DEBUG
|
||||||
PFN_vkDestroyDebugReportCallbackEXT vkDestroyDebugReportCallback = reinterpret_cast<PFN_vkDestroyDebugReportCallbackEXT>(vkGetInstanceProcAddr(instance, "vkDestroyDebugReportCallbackEXT"));
|
PFN_vkDestroyDebugReportCallbackEXT vkDestroyDebugReportCallback = reinterpret_cast<PFN_vkDestroyDebugReportCallbackEXT>(vkGetInstanceProcAddr(instance, "vkDestroyDebugReportCallbackEXT"));
|
||||||
assert(vkDestroyDebugReportCallback);
|
assert(vkDestroyDebugReportCallback);
|
||||||
vkDestroyDebugReportCallback(instance, debugReportCallback, nullptr);
|
vkDestroyDebugReportCallback(instance, debugReportCallback, nullptr);
|
||||||
|
|
@ -451,15 +486,28 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#if defined(__ANDROID__)
|
#if defined(VK_USE_PLATFORM_ANDROID_KHR)
|
||||||
// Android entry point
|
void handleAppCommand(android_app * app, int32_t cmd) {
|
||||||
// A note on app_dummy(): This is required as the compiler may otherwise remove the main entry point of the application
|
if (cmd == APP_CMD_INIT_WINDOW) {
|
||||||
VulkanExample *vulkanExample;
|
VulkanExample *vulkanExample = new VulkanExample();
|
||||||
|
delete(vulkanExample);
|
||||||
|
ANativeActivity_finish(app->activity);
|
||||||
|
}
|
||||||
|
}
|
||||||
void android_main(android_app* state) {
|
void android_main(android_app* state) {
|
||||||
app_dummy();
|
app_dummy();
|
||||||
VulkanExample *vulkanExample = new VulkanExample();
|
androidapp = state;
|
||||||
state->userData = vulkanExample;
|
androidapp->onAppCmd = handleAppCommand;
|
||||||
delete(vulkanExample);
|
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
|
#else
|
||||||
int main() {
|
int main() {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue