├── .gitignore
├── LICENSE
├── README.md
├── app
├── .gitignore
├── CMakeLists.txt
├── build.gradle
├── conanfile.txt
├── debug.keystore
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── assets
│ └── sample_tex.png
│ ├── cpp
│ ├── vulkan_tutorial.cpp
│ ├── vulkan_tutorial.h
│ ├── vulkan_tutorial_jni.cpp
│ └── vulkan_wrapper
│ │ ├── vulkan_wrapper.cpp
│ │ └── vulkan_wrapper.h
│ ├── java
│ └── com
│ │ └── github
│ │ └── piasy
│ │ └── vulkantutorial
│ │ ├── MainActivity.java
│ │ └── VulkanTutorialApplication.java
│ ├── res
│ ├── layout
│ │ └── activity_main.xml
│ ├── mipmap-hdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ ├── mipmap-mdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ ├── mipmap-xhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ ├── mipmap-xxhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ ├── mipmap-xxxhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ └── values
│ │ ├── colors.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ └── shaders
│ ├── triangle.frag
│ └── triangle.vert
├── build.gradle
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | **.iml
2 | .gradle
3 | /local.properties
4 | /.idea/
5 | .DS_Store
6 | /build
7 | /captures
8 | .externalNativeBuild
9 | /app/conan_build/
10 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Piasy
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # VulkanTutorial-Android
2 |
3 | Step by step tutorial of Vulkan on Android, follow https://vulkan-tutorial.com.
4 |
5 | + We need [`vulkan_wrapper`](https://developer.android.com/ndk/guides/graphics/getting-started.html#using) on Android, which could be [download from GitHub](https://github.com/LunarG/VulkanSamples/tree/master/common).
6 | + In Android Studio, just put shader code under `src/main/shaders` folder, they will be compiled into `.spv` files, and packaged as assets.
7 |
8 | ## Conan package manager
9 |
10 | Conan support is setup according to [this tutorial](https://docs.conan.io/en/latest/integrations/android_studio.html), to install conan, run `pip install conan`.
11 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | # For more information about using CMake with Android Studio, read the
2 | # documentation: https://d.android.com/studio/projects/add-native-code.html
3 |
4 | # Sets the minimum version of CMake required to build the native library.
5 |
6 | cmake_minimum_required(VERSION 3.4.1)
7 |
8 | include(${CMAKE_CURRENT_SOURCE_DIR}/conan_build/conanbuildinfo.cmake)
9 | set(CMAKE_CXX_COMPILER_VERSION "5.0") # Unknown miss-detection of the compiler by CMake
10 | conan_basic_setup(TARGETS)
11 |
12 | # Creates and names a library, sets it as either STATIC
13 | # or SHARED, and provides the relative paths to its source code.
14 | # You can define multiple libraries, and CMake builds them for you.
15 | # Gradle automatically packages shared libraries with your APK.
16 |
17 | # build vulkan app
18 | set(SRC_DIR src/main/cpp)
19 | set(VK_WRAPPER_DIR src/main/cpp/vulkan_wrapper)
20 | set(VK_VAL_LAYER_SRC_DIR ${ANDROID_NDK}/sources/third_party/vulkan/src)
21 |
22 | add_library( # Sets the name of the library.
23 | vulkan-tutorial
24 |
25 | # Sets the library as a shared library.
26 | SHARED
27 |
28 | # Provides a relative path to your source file(s).
29 | ${VK_WRAPPER_DIR}/vulkan_wrapper.cpp
30 | ${SRC_DIR}/vulkan_tutorial.cpp
31 | ${SRC_DIR}/vulkan_tutorial_jni.cpp
32 | )
33 |
34 | include_directories(${VK_WRAPPER_DIR} ${VK_VAL_LAYER_SRC_DIR}/include ${CONAN_INCLUDE_DIRS})
35 |
36 | # Searches for a specified prebuilt library and stores the path as a
37 | # variable. Because CMake includes system libraries in the search path by
38 | # default, you only need to specify the name of the public NDK library
39 | # you want to add. CMake verifies that the library exists before
40 | # completing its build.
41 |
42 | find_library( # Sets the name of the path variable.
43 | log-lib
44 |
45 | # Specifies the name of the NDK library that
46 | # you want CMake to locate.
47 | log )
48 |
49 | # Specifies libraries CMake should link to your target library. You
50 | # can link multiple libraries, such as libraries you define in this
51 | # build script, prebuilt third-party libraries, or system libraries.
52 |
53 | target_link_libraries( # Specifies the target library.
54 | vulkan-tutorial
55 |
56 | ${CONAN_LIBS}
57 |
58 | # Links the target library to the log library
59 | # included in the NDK.
60 | ${log-lib}
61 | android)
62 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | Properties properties = new Properties()
4 | properties.load(project.rootProject.file('local.properties').newDataInputStream())
5 | def ndkDir = properties.getProperty('ndk.dir')
6 | def valLayerBinDir = "${ndkDir}/sources/third_party/vulkan/src/build-android/jniLibs"
7 |
8 | android {
9 | compileSdkVersion 27
10 | buildToolsVersion "27.0.3"
11 | defaultConfig {
12 | applicationId "com.github.piasy.vulkantutorial"
13 | minSdkVersion 24
14 | targetSdkVersion 27
15 | versionCode 1
16 | versionName "1.0"
17 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
18 |
19 | externalNativeBuild {
20 | cmake {
21 | cppFlags "-frtti -fexceptions -std=c++11 -Werror -Wno-unused-variable"
22 | }
23 | }
24 |
25 | ndk.abiFilters = ['armeabi-v7a']
26 | }
27 |
28 | sourceSets {
29 | debug {
30 | ndkDir = 'src/main/cpp'
31 | jniLibs {
32 | // Must have ndk-r12 or better which including layer binaries
33 | srcDirs = ["${valLayerBinDir}"]
34 | }
35 | }
36 | }
37 |
38 | signingConfigs {
39 | debug {
40 | storeFile file('debug.keystore')
41 | }
42 | }
43 |
44 | buildTypes {
45 | debug {
46 | debuggable true
47 | minifyEnabled false
48 | signingConfig signingConfigs.debug
49 |
50 | externalNativeBuild {
51 | cmake {
52 | cppFlags "-DUSE_DEBUG_EXTENTIONS -DVK_USE_PLATFORM_ANDROID_KHR"
53 | }
54 | }
55 | }
56 | release {
57 | minifyEnabled false
58 | signingConfig signingConfigs.debug
59 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
60 |
61 | externalNativeBuild {
62 | cmake {
63 | cppFlags "-DVK_USE_PLATFORM_ANDROID_KHR"
64 | }
65 | }
66 | }
67 | }
68 |
69 | externalNativeBuild {
70 | cmake {
71 | path "CMakeLists.txt"
72 | }
73 | }
74 | }
75 |
76 | task conanInstall {
77 | def buildDir = new File("app/conan_build")
78 | buildDir.mkdirs()
79 | // if you have problems running the command try to specify the absolute
80 | // path to conan (Known problem in MacOSX) /usr/local/bin/conan
81 | def cmd = "conan install ../conanfile.txt --profile android_21_arm_clang --build missing"
82 | print(">> ${cmd} \n")
83 |
84 | def sout = new StringBuilder(), serr = new StringBuilder()
85 | def proc = cmd.execute(null, buildDir)
86 | proc.consumeProcessOutput(sout, serr)
87 | proc.waitFor()
88 | println "$sout $serr"
89 | if (proc.exitValue() != 0) {
90 | throw new Exception("out> $sout err> $serr" + "\nCommand: ${cmd}")
91 | }
92 | }
93 |
94 | dependencies {
95 | implementation 'com.android.support:appcompat-v7:27.1.1'
96 | }
97 |
--------------------------------------------------------------------------------
/app/conanfile.txt:
--------------------------------------------------------------------------------
1 | [requires]
2 | glm/0.9.8.5@g-truc/stable
3 | stb/20180214@conan/stable
4 |
5 | [generators]
6 | cmake
7 |
--------------------------------------------------------------------------------
/app/debug.keystore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Piasy/VulkanTutorial-Android/7c295c1acb052acfa901a61b896b617aa273e817/app/debug.keystore
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /Users/piasy/tools/android-sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
19 | # Uncomment this to preserve the line number information for
20 | # debugging stack traces.
21 | #-keepattributes SourceFile,LineNumberTable
22 |
23 | # If you keep the line number information, uncomment this to
24 | # hide the original source file name.
25 | #-renamesourcefileattribute SourceFile
26 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/app/src/main/assets/sample_tex.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Piasy/VulkanTutorial-Android/7c295c1acb052acfa901a61b896b617aa273e817/app/src/main/assets/sample_tex.png
--------------------------------------------------------------------------------
/app/src/main/cpp/vulkan_tutorial.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // Created by Piasy on 26/06/2017.
3 | //
4 |
5 | #include
6 | #include
7 | #include
8 | #include
9 |
10 | #define GLM_FORCE_RADIANS
11 | #include
12 |
13 | #define STB_IMAGE_IMPLEMENTATION
14 | #include
15 |
16 | #include "vulkan_tutorial.h"
17 |
18 | const int WIDTH = 800;
19 | const int HEIGHT = 448;
20 |
21 | const std::vector validationLayers = {
22 | "VK_LAYER_LUNARG_image",
23 | "VK_LAYER_GOOGLE_threading",
24 | "VK_LAYER_LUNARG_core_validation",
25 | "VK_LAYER_LUNARG_object_tracker",
26 | "VK_LAYER_LUNARG_swapchain",
27 | "VK_LAYER_LUNARG_parameter_validation",
28 | "VK_LAYER_GOOGLE_unique_objects",
29 | };
30 |
31 | const std::vector deviceExtensions = {
32 | VK_KHR_SWAPCHAIN_EXTENSION_NAME
33 | };
34 |
35 | const std::vector vertices = {
36 | {{-0.5f, -0.5f}, {1.0f, 0.0f, 0.0f}, {1.0f, 0.0f}},
37 | {{0.5f, -0.5f}, {0.0f, 1.0f, 0.0f}, {0.0f, 0.0f}},
38 | {{0.5f, 0.5f}, {0.0f, 0.0f, 1.0f}, {0.0f, 1.0f}},
39 | {{-0.5f, 0.5f}, {1.0f, 1.0f, 1.0f}, {1.0f, 1.0f}}
40 | };
41 | const std::vector indices = {
42 | 0, 1, 2, 2, 3, 0
43 | };
44 |
45 | const std::string IMAGE_PATH = "sample_tex.png";
46 |
47 | #ifdef USE_DEBUG_EXTENTIONS
48 | const bool enableValidationLayers = true;
49 | #else
50 | const bool enableValidationLayers = false;
51 | #endif
52 |
53 | VkResult CreateDebugReportCallbackEXT(
54 | VkInstance instance,
55 | const VkDebugReportCallbackCreateInfoEXT *pCreateInfo,
56 | const VkAllocationCallbacks *pAllocator,
57 | VkDebugReportCallbackEXT *pCallback) {
58 | auto func = (PFN_vkCreateDebugReportCallbackEXT) vkGetInstanceProcAddr(instance,
59 | "vkCreateDebugReportCallbackEXT");
60 | if (func != nullptr) {
61 | return func(instance, pCreateInfo, pAllocator, pCallback);
62 | } else {
63 | return VK_ERROR_EXTENSION_NOT_PRESENT;
64 | }
65 | }
66 |
67 | void DestroyDebugReportCallbackEXT(
68 | VkInstance instance,
69 | VkDebugReportCallbackEXT callback,
70 | const VkAllocationCallbacks *pAllocator) {
71 | auto func = (PFN_vkDestroyDebugReportCallbackEXT) vkGetInstanceProcAddr(instance,
72 | "vkDestroyDebugReportCallbackEXT");
73 | if (func != nullptr) {
74 | func(instance, callback, pAllocator);
75 | }
76 | }
77 |
78 | static VKAPI_ATTR VkBool32 VKAPI_CALL debugCallback(
79 | VkDebugReportFlagsEXT flags,
80 | VkDebugReportObjectTypeEXT objType,
81 | uint64_t obj,
82 | size_t location,
83 | int32_t code,
84 | const char *layerPrefix,
85 | const char *msg,
86 | void *userData) {
87 | if (flags & VK_DEBUG_REPORT_ERROR_BIT_EXT) {
88 | __android_log_print(ANDROID_LOG_ERROR,
89 | APP_NAME,
90 | "ERROR: [%s] Code %i : %s",
91 | layerPrefix, code, msg);
92 | } else if (flags & VK_DEBUG_REPORT_WARNING_BIT_EXT) {
93 | __android_log_print(ANDROID_LOG_WARN,
94 | APP_NAME,
95 | "WARNING: [%s] Code %i : %s",
96 | layerPrefix, code, msg);
97 | } else if (flags & VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT) {
98 | __android_log_print(ANDROID_LOG_WARN,
99 | APP_NAME,
100 | "PERFORMANCE WARNING: [%s] Code %i : %s",
101 | layerPrefix, code, msg);
102 | } else if (flags & VK_DEBUG_REPORT_INFORMATION_BIT_EXT) {
103 | __android_log_print(ANDROID_LOG_INFO,
104 | APP_NAME,
105 | "INFO: [%s] Code %i : %s",
106 | layerPrefix, code, msg);
107 | } else if (flags & VK_DEBUG_REPORT_DEBUG_BIT_EXT) {
108 | __android_log_print(ANDROID_LOG_VERBOSE,
109 | APP_NAME,
110 | "DEBUG: [%s] Code %i : %s",
111 | layerPrefix, code, msg);
112 | }
113 |
114 | // Returning false tells the layer not to stop when the event occurs, so
115 | // they see the same behavior with and without validation layers enabled.
116 | return VK_FALSE;
117 | }
118 |
119 | VkSurfaceFormatKHR chooseSwapSurfaceFormat(
120 | const std::vector &availableFormats) {
121 | if (availableFormats.size() == 1 && availableFormats[0].format == VK_FORMAT_UNDEFINED) {
122 | return {VK_FORMAT_B8G8R8_UNORM, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR};
123 | }
124 |
125 | for (const auto &format : availableFormats) {
126 | if (format.format == VK_FORMAT_B8G8R8_UNORM
127 | && format.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) {
128 | return format;
129 | }
130 | }
131 |
132 | return availableFormats[0];
133 | }
134 |
135 | VkPresentModeKHR chooseSwapPresentMode(
136 | const std::vector &availablePresentModes) {
137 | VkPresentModeKHR bestMode = VK_PRESENT_MODE_FIFO_KHR;
138 |
139 | for (const auto &mode : availablePresentModes) {
140 | if (mode == VK_PRESENT_MODE_MAILBOX_KHR) {
141 | return mode;
142 | } else if (mode == VK_PRESENT_MODE_IMMEDIATE_KHR) {
143 | bestMode = mode;
144 | }
145 | }
146 |
147 | return bestMode;
148 | }
149 |
150 | VkExtent2D chooseSwapExtent(const VkSurfaceCapabilitiesKHR &capabilities) {
151 | if (capabilities.currentExtent.width != std::numeric_limits::max()) {
152 | return capabilities.currentExtent;
153 | }
154 |
155 | VkExtent2D actualExtent = {WIDTH, HEIGHT};
156 | actualExtent.width = std::max(
157 | capabilities.minImageExtent.width,
158 | std::min(capabilities.maxImageExtent.width, actualExtent.width)
159 | );
160 | actualExtent.height = std::max(
161 | capabilities.minImageExtent.height,
162 | std::min(capabilities.maxImageExtent.height, actualExtent.height)
163 | );
164 |
165 | return actualExtent;
166 | }
167 |
168 | bool supportValidationLayers() {
169 | uint32_t layerCount = 0;
170 | vkEnumerateInstanceLayerProperties(&layerCount, nullptr);
171 |
172 | LOGI("layer count: %d", layerCount);
173 |
174 | std::vector availableLayers(layerCount);
175 | vkEnumerateInstanceLayerProperties(&layerCount, availableLayers.data());
176 |
177 | for (const auto &layer : availableLayers) {
178 | LOGI("\t layer: %s", layer.layerName);
179 | }
180 |
181 | for (const char *layerName : validationLayers) {
182 | bool found = false;
183 | for (const auto &layer : availableLayers) {
184 | if (strcmp(layerName, layer.layerName) == 0) {
185 | found = true;
186 | break;
187 | }
188 | }
189 |
190 | if (!found) {
191 | return false;
192 | }
193 | }
194 |
195 | return true;
196 | }
197 |
198 | std::vector requiredExtensions() {
199 | std::vector extensionNames;
200 | uint32_t extensionCount = 0;
201 | vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, nullptr);
202 |
203 | LOGI("extension count: %d", extensionCount);
204 |
205 | std::vector extensions(extensionCount);
206 | vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, extensions.data());
207 |
208 | for (const auto &extension : extensions) {
209 | if (strcmp(VK_EXT_DEBUG_REPORT_EXTENSION_NAME, extension.extensionName) == 0) {
210 | if (enableValidationLayers) {
211 | extensionNames.push_back(extension.extensionName);
212 | }
213 | } else {
214 | extensionNames.push_back(extension.extensionName);
215 | }
216 |
217 | LOGI("\t extension: %s", extension.extensionName);
218 | }
219 | return extensionNames;
220 | }
221 |
222 | void VulkanTutorialApplication::run(ANativeWindow *window) {
223 | initWindow(window);
224 | initVulkan();
225 | mainLoop();
226 | cleanUp();
227 | }
228 |
229 | void VulkanTutorialApplication::pause() {
230 | state = STATE_PAUSED;
231 | vkDeviceWaitIdle(device);
232 | }
233 |
234 | void VulkanTutorialApplication::surfaceChanged() {
235 | state = STATE_PAUSED;
236 | recreateSwapchain();
237 | state = STATE_RUNNING;
238 | }
239 |
240 | void VulkanTutorialApplication::initVulkan() {
241 | if (!InitVulkan()) {
242 | throw std::runtime_error("InitVulkan fail!");
243 | }
244 |
245 | createInstance();
246 | setUpDebugCallback();
247 | createSurface();
248 |
249 | pickPhysicalDevice();
250 | createLogicalDevice();
251 |
252 | createSwapchain();
253 | createImageViews();
254 | createRenderPass();
255 | createDescriptorSetLayout();
256 | createGraphicsPipeline();
257 | createFramebuffers();
258 |
259 | createCommandPool();
260 | createTextureImage();
261 | createTextureImageView();
262 | createTextureSampler();
263 |
264 | createVertexBuffer();
265 | createIndexBuffer();
266 | createUniformBuffer();
267 | createDescriptorPool();
268 | createDescriptorSet();
269 | createCommandBuffers();
270 |
271 | createSemaphores();
272 | }
273 |
274 | void VulkanTutorialApplication::mainLoop() {
275 | LOGI("mainLoop start");
276 |
277 | while (state != STATE_EXIT) {
278 | if (state == STATE_RUNNING) {
279 | updateUniformBuffer();
280 | drawFrame();
281 | }
282 | }
283 |
284 | vkDeviceWaitIdle(device);
285 |
286 | LOGI("mainLoop exit");
287 | }
288 |
289 | void VulkanTutorialApplication::cleanUp() {
290 | cleanupSwapchain();
291 |
292 | vkDestroyDescriptorPool(device, descriptorPool, nullptr);
293 | vkDestroyDescriptorSetLayout(device, descriptorSetLayout, nullptr);
294 | vkDestroyBuffer(device, uniformBuffer, nullptr);
295 | vkFreeMemory(device, uniformBufferMemory, nullptr);
296 |
297 | vkDestroyBuffer(device, indexBuffer, nullptr);
298 | vkFreeMemory(device, indexBufferMemory, nullptr);
299 |
300 | vkDestroyBuffer(device, vertexBuffer, nullptr);
301 | vkFreeMemory(device, vertexBufferMemory, nullptr);
302 |
303 | vkDestroySemaphore(device, renderFinishedSemaphore, nullptr);
304 | vkDestroySemaphore(device, imageAvailableSemaphore, nullptr);
305 |
306 | vkDestroyCommandPool(device, commandPool, nullptr);
307 |
308 | vkDestroyDevice(device, nullptr);
309 | DestroyDebugReportCallbackEXT(instance, callback, nullptr);
310 | vkDestroySurfaceKHR(instance, surface, nullptr);
311 | vkDestroyInstance(instance, nullptr);
312 |
313 | ANativeWindow_release(window);
314 | }
315 |
316 | void VulkanTutorialApplication::createInstance() {
317 | if (enableValidationLayers && !supportValidationLayers()) {
318 | throw std::runtime_error("validation layers requested, but not available!");
319 | }
320 |
321 | VkApplicationInfo appInfo = {
322 | .sType = VK_STRUCTURE_TYPE_APPLICATION_INFO,
323 | .pApplicationName = "Hello Triangle",
324 | .applicationVersion = VK_MAKE_VERSION(1, 0, 0),
325 | .pEngineName = "No Engine",
326 | .engineVersion = VK_MAKE_VERSION(1, 0, 0),
327 | .apiVersion = VK_API_VERSION_1_0,
328 | };
329 |
330 | auto extensions = requiredExtensions();
331 | VkInstanceCreateInfo createInfo = {
332 | .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
333 | .pApplicationInfo = &appInfo,
334 | .enabledExtensionCount = static_cast(extensions.size()),
335 | .ppEnabledExtensionNames = extensions.data(),
336 | };
337 | if (enableValidationLayers) {
338 | createInfo.enabledLayerCount = static_cast(validationLayers.size());
339 | createInfo.ppEnabledLayerNames = validationLayers.data();
340 | } else {
341 | createInfo.enabledLayerCount = 0;
342 | }
343 |
344 | if (vkCreateInstance(&createInfo, nullptr, &instance) != VK_SUCCESS) {
345 | throw std::runtime_error("create instance fail!");
346 | }
347 |
348 | LOGI("createInstance success :)");
349 | }
350 |
351 | void VulkanTutorialApplication::setUpDebugCallback() {
352 | if (!enableValidationLayers) {
353 | return;
354 | }
355 |
356 | VkDebugReportCallbackCreateInfoEXT createInfo = {};
357 | createInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT;
358 | createInfo.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT
359 | | VK_DEBUG_REPORT_WARNING_BIT_EXT
360 | | VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT;
361 | createInfo.pfnCallback = debugCallback;
362 |
363 | if (CreateDebugReportCallbackEXT(instance, &createInfo, nullptr, &callback) != VK_SUCCESS) {
364 | throw std::runtime_error("failed to set up debug callback!");
365 | }
366 | }
367 |
368 | void VulkanTutorialApplication::createSurface() {
369 | VkAndroidSurfaceCreateInfoKHR createInfo = {};
370 | createInfo.sType = VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR;
371 | createInfo.window = window;
372 |
373 | if (vkCreateAndroidSurfaceKHR(instance, &createInfo, nullptr, &surface) != VK_SUCCESS) {
374 | throw std::runtime_error("failed to create window surface!");
375 | }
376 | }
377 |
378 | void VulkanTutorialApplication::pickPhysicalDevice() {
379 | uint32_t deviceCount = 0;
380 | vkEnumeratePhysicalDevices(instance, &deviceCount, nullptr);
381 |
382 | LOGI("device count: %d", deviceCount);
383 |
384 | if (deviceCount == 0) {
385 | throw std::runtime_error("failed to find GPUs with Vulkan support!");
386 | }
387 |
388 | std::vector devices(deviceCount);
389 | vkEnumeratePhysicalDevices(instance, &deviceCount, devices.data());
390 |
391 | for (const auto &device : devices) {
392 | if (isDeviceSuitable(device)) {
393 | physicalDevice = device;
394 | break;
395 | }
396 | }
397 |
398 | if (physicalDevice == VK_NULL_HANDLE) {
399 | throw std::runtime_error("failed to find a suitable GPU!");
400 | }
401 | }
402 |
403 | void VulkanTutorialApplication::createLogicalDevice() {
404 | QueueFamilyIndices indices = findQueueFamilies(physicalDevice);
405 |
406 | std::vector queueCreateInfos;
407 | std::set uniqueQueueFamilies = {indices.graphicsFamily, indices.presentFamily};
408 | float queuePriority = 1.0F;
409 |
410 | for (int queueFamily : uniqueQueueFamilies) {
411 | VkDeviceQueueCreateInfo queueCreateInfo = {};
412 | queueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
413 | queueCreateInfo.queueFamilyIndex = queueFamily;
414 | queueCreateInfo.queueCount = 1;
415 | queueCreateInfo.pQueuePriorities = &queuePriority;
416 |
417 | queueCreateInfos.push_back(queueCreateInfo);
418 | }
419 |
420 | VkPhysicalDeviceFeatures deviceFeatures = {};
421 |
422 | VkDeviceCreateInfo createInfo = {};
423 | createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
424 | createInfo.pQueueCreateInfos = queueCreateInfos.data();
425 | createInfo.queueCreateInfoCount = static_cast(queueCreateInfos.size());
426 | createInfo.pEnabledFeatures = &deviceFeatures;
427 | createInfo.enabledExtensionCount = static_cast(deviceExtensions.size());
428 | createInfo.ppEnabledExtensionNames = deviceExtensions.data();
429 |
430 | if (enableValidationLayers) {
431 | createInfo.enabledLayerCount = static_cast(validationLayers.size());
432 | createInfo.ppEnabledLayerNames = validationLayers.data();
433 | } else {
434 | createInfo.enabledLayerCount = 0;
435 | }
436 |
437 | if (vkCreateDevice(physicalDevice, &createInfo, nullptr, &device) != VK_SUCCESS) {
438 | throw std::runtime_error("failed to create logical device!");
439 | }
440 |
441 | vkGetDeviceQueue(device, indices.graphicsFamily, 0, &graphicsQueue);
442 | vkGetDeviceQueue(device, indices.presentFamily, 0, &presentQueue);
443 | }
444 |
445 | void VulkanTutorialApplication::createSwapchain() {
446 | SwapchainSupportDetails swapchainSupport = querySwapchainSupport(physicalDevice);
447 | VkSurfaceFormatKHR surfaceFormat = chooseSwapSurfaceFormat(swapchainSupport.formats);
448 | VkPresentModeKHR presentMode = chooseSwapPresentMode(swapchainSupport.presentModes);
449 | VkExtent2D extent = chooseSwapExtent(swapchainSupport.capabilities);
450 |
451 | uint32_t imageCount = swapchainSupport.capabilities.minImageCount + 1;
452 | if (swapchainSupport.capabilities.maxImageCount > 0
453 | && imageCount > swapchainSupport.capabilities.maxImageCount) {
454 | imageCount = swapchainSupport.capabilities.maxImageCount;
455 | }
456 |
457 | VkSwapchainCreateInfoKHR createInfo = {};
458 | createInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
459 | createInfo.surface = surface;
460 | createInfo.minImageCount = imageCount;
461 | createInfo.imageFormat = surfaceFormat.format;
462 | createInfo.imageColorSpace = surfaceFormat.colorSpace;
463 | createInfo.imageExtent = extent;
464 | createInfo.imageArrayLayers = 1;
465 | createInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
466 |
467 | QueueFamilyIndices indices = findQueueFamilies(physicalDevice);
468 | if (indices.graphicsFamily != indices.presentFamily) {
469 | uint32_t queueFamilyIndices[] = {
470 | (uint32_t) indices.graphicsFamily, (uint32_t) indices.presentFamily
471 | };
472 | createInfo.imageSharingMode = VK_SHARING_MODE_CONCURRENT;
473 | createInfo.queueFamilyIndexCount = 2;
474 | createInfo.pQueueFamilyIndices = queueFamilyIndices;
475 | } else {
476 | createInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
477 | }
478 |
479 | createInfo.preTransform = swapchainSupport.capabilities.currentTransform;
480 | createInfo.compositeAlpha = VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR;
481 | createInfo.presentMode = presentMode;
482 | createInfo.clipped = VK_TRUE;
483 | createInfo.oldSwapchain = VK_NULL_HANDLE;
484 |
485 | if (vkCreateSwapchainKHR(device, &createInfo, nullptr, &swapchain) != VK_SUCCESS) {
486 | throw std::runtime_error("failed to create swap chain!");
487 | }
488 |
489 | vkGetSwapchainImagesKHR(device, swapchain, &imageCount, nullptr);
490 | swapchainImages.resize(imageCount);
491 | vkGetSwapchainImagesKHR(device, swapchain, &imageCount, swapchainImages.data());
492 |
493 | swapchainImageFormat = surfaceFormat.format;
494 | swapchainExtent = extent;
495 | }
496 |
497 | void VulkanTutorialApplication::createImageViews() {
498 | swapchainImageViews.resize(swapchainImages.size());
499 | for (size_t i = 0; i < swapchainImages.size(); i++) {
500 | VkImageViewCreateInfo createInfo = {};
501 | createInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
502 | createInfo.image = swapchainImages[i];
503 |
504 | createInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
505 | createInfo.format = swapchainImageFormat;
506 |
507 | createInfo.components.r = VK_COMPONENT_SWIZZLE_IDENTITY;
508 | createInfo.components.g = VK_COMPONENT_SWIZZLE_IDENTITY;
509 | createInfo.components.b = VK_COMPONENT_SWIZZLE_IDENTITY;
510 | createInfo.components.a = VK_COMPONENT_SWIZZLE_IDENTITY;
511 |
512 | createInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
513 | createInfo.subresourceRange.baseMipLevel = 0;
514 | createInfo.subresourceRange.levelCount = 1;
515 | createInfo.subresourceRange.baseArrayLayer = 0;
516 | createInfo.subresourceRange.layerCount = 1;
517 |
518 | if (vkCreateImageView(device, &createInfo, nullptr, &swapchainImageViews[i]) !=
519 | VK_SUCCESS) {
520 | throw std::runtime_error("failed to create image views!");
521 | }
522 | }
523 | }
524 |
525 | void VulkanTutorialApplication::createRenderPass() {
526 | VkAttachmentDescription colorAttachment = {};
527 | colorAttachment.format = swapchainImageFormat;
528 | colorAttachment.samples = VK_SAMPLE_COUNT_1_BIT;
529 | colorAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
530 | colorAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
531 | colorAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
532 | colorAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
533 | colorAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
534 | colorAttachment.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
535 |
536 | VkAttachmentReference colorAttachmentRef = {};
537 | colorAttachmentRef.attachment = 0;
538 | colorAttachmentRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
539 |
540 | VkSubpassDescription subpass = {};
541 | subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
542 | subpass.colorAttachmentCount = 1;
543 | subpass.pColorAttachments = &colorAttachmentRef;
544 |
545 | VkRenderPassCreateInfo renderPassInfo = {};
546 | renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
547 | renderPassInfo.attachmentCount = 1;
548 | renderPassInfo.pAttachments = &colorAttachment;
549 | renderPassInfo.subpassCount = 1;
550 | renderPassInfo.pSubpasses = &subpass;
551 |
552 | if (vkCreateRenderPass(device, &renderPassInfo, nullptr, &renderPass) != VK_SUCCESS) {
553 | throw std::runtime_error("failed to create render pass!");
554 | }
555 | }
556 |
557 | void VulkanTutorialApplication::createDescriptorSetLayout() {
558 | VkDescriptorSetLayoutBinding uboLayoutBinding = {
559 | .binding = 0,
560 | .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
561 | .descriptorCount = 1,
562 | .stageFlags = VK_SHADER_STAGE_VERTEX_BIT,
563 | .pImmutableSamplers = nullptr,
564 | };
565 |
566 | VkDescriptorSetLayoutBinding samplerLayoutBinding = {
567 | .binding = 1,
568 | .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
569 | .descriptorCount = 1,
570 | .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT,
571 | .pImmutableSamplers = nullptr,
572 | };
573 |
574 | std::array bindings = {uboLayoutBinding,samplerLayoutBinding};
575 |
576 | VkDescriptorSetLayoutCreateInfo layoutInfo = {
577 | .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
578 | .bindingCount = static_cast(bindings.size()),
579 | .pBindings = bindings.data(),
580 | };
581 |
582 | if (vkCreateDescriptorSetLayout(device, &layoutInfo, nullptr, &descriptorSetLayout)
583 | != VK_SUCCESS) {
584 | throw std::runtime_error("failed to create descriptor set layout!");
585 | }
586 | }
587 |
588 | void VulkanTutorialApplication::createGraphicsPipeline() {
589 | auto vertexShaderCode = readAsset(vertexShader);
590 | auto fragmentShaderCode = readAsset(fragmentShader);
591 | VkShaderModule vertexShaderModule = createShaderModule(vertexShaderCode);
592 | VkShaderModule fragmentShaderModule = createShaderModule(fragmentShaderCode);
593 | VkPipelineShaderStageCreateInfo vertexShaderStageInfo = {
594 | .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
595 | .stage = VK_SHADER_STAGE_VERTEX_BIT,
596 | .module = vertexShaderModule,
597 | .pName = "main",
598 | };
599 | VkPipelineShaderStageCreateInfo fragmentShaderStageInfo = {
600 | .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
601 | .stage = VK_SHADER_STAGE_FRAGMENT_BIT,
602 | .module = fragmentShaderModule,
603 | .pName = "main",
604 | };
605 | VkPipelineShaderStageCreateInfo shaderStages[] = {
606 | vertexShaderStageInfo, fragmentShaderStageInfo
607 | };
608 |
609 | auto bindingDesc = Vertex::getBindingDescription();
610 | auto attrDesc = Vertex::getAttributeDescriptions();
611 | VkPipelineVertexInputStateCreateInfo vertexInputInfo = {
612 | .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
613 | .vertexBindingDescriptionCount = 1,
614 | .vertexAttributeDescriptionCount = static_cast(attrDesc.size()),
615 | .pVertexBindingDescriptions = &bindingDesc,
616 | .pVertexAttributeDescriptions = attrDesc.data(),
617 | };
618 |
619 | VkPipelineInputAssemblyStateCreateInfo inputAssembly = {
620 | .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
621 | .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
622 | .primitiveRestartEnable = VK_FALSE,
623 | };
624 |
625 | VkViewport viewport = {
626 | .x = 0.0f,
627 | .y = 0.0f,
628 | .width = (float) swapchainExtent.width,
629 | .height = (float) swapchainExtent.height,
630 | .minDepth = 0.0f,
631 | .maxDepth = 1.0f,
632 | };
633 |
634 | VkRect2D scissor = {
635 | .offset = {0, 0},
636 | .extent = swapchainExtent,
637 | };
638 |
639 | VkPipelineViewportStateCreateInfo viewportState = {
640 | .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
641 | .viewportCount = 1,
642 | .pViewports = &viewport,
643 | .scissorCount = 1,
644 | .pScissors = &scissor,
645 | };
646 |
647 | VkPipelineRasterizationStateCreateInfo rasterizer = {
648 | .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
649 | .depthClampEnable = VK_FALSE,
650 | .rasterizerDiscardEnable = VK_FALSE,
651 | .polygonMode = VK_POLYGON_MODE_FILL,
652 | .lineWidth = 1.0f,
653 | .cullMode = VK_CULL_MODE_BACK_BIT,
654 | .frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE,
655 | .depthBiasEnable = VK_FALSE,
656 | };
657 |
658 | VkPipelineMultisampleStateCreateInfo multisampling = {
659 | .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
660 | .sampleShadingEnable = VK_FALSE,
661 | .rasterizationSamples = VK_SAMPLE_COUNT_1_BIT,
662 | };
663 |
664 | VkPipelineColorBlendAttachmentState colorBlendAttachment = {
665 | .colorWriteMask = VK_COLOR_COMPONENT_R_BIT
666 | | VK_COLOR_COMPONENT_G_BIT
667 | | VK_COLOR_COMPONENT_B_BIT
668 | | VK_COLOR_COMPONENT_A_BIT,
669 | .blendEnable = VK_FALSE,
670 | };
671 | VkPipelineColorBlendStateCreateInfo colorBlending = {
672 | .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
673 | .logicOpEnable = VK_FALSE,
674 | .logicOp = VK_LOGIC_OP_COPY,
675 | .attachmentCount = 1,
676 | .pAttachments = &colorBlendAttachment,
677 | .blendConstants[0] = 0.0f,
678 | .blendConstants[1] = 0.0f,
679 | .blendConstants[2] = 0.0f,
680 | .blendConstants[3] = 0.0f,
681 | };
682 |
683 | VkPipelineLayoutCreateInfo pipelineLayoutInfo = {
684 | .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
685 | .setLayoutCount = 1,
686 | .pSetLayouts = &descriptorSetLayout,
687 | };
688 | if (vkCreatePipelineLayout(device, &pipelineLayoutInfo, nullptr, &pipelineLayout)
689 | != VK_SUCCESS) {
690 | throw std::runtime_error("failed to create pipeline layout!");
691 | }
692 |
693 | VkGraphicsPipelineCreateInfo pipelineInfo = {
694 | .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
695 | .stageCount = 2,
696 | .pStages = shaderStages,
697 | .pVertexInputState = &vertexInputInfo,
698 | .pInputAssemblyState = &inputAssembly,
699 | .pViewportState = &viewportState,
700 | .pRasterizationState = &rasterizer,
701 | .pMultisampleState = &multisampling,
702 | .pColorBlendState = &colorBlending,
703 | .layout = pipelineLayout,
704 | .renderPass = renderPass,
705 | .subpass = 0,
706 | .basePipelineHandle = VK_NULL_HANDLE,
707 | };
708 |
709 | if (vkCreateGraphicsPipelines(device, VK_NULL_HANDLE, 1, &pipelineInfo, nullptr,
710 | &graphicsPipeline) != VK_SUCCESS) {
711 | throw std::runtime_error("failed to create graphics pipeline!");
712 | }
713 |
714 | vkDestroyShaderModule(device, vertexShaderModule, nullptr);
715 | vkDestroyShaderModule(device, fragmentShaderModule, nullptr);
716 | }
717 |
718 | void VulkanTutorialApplication::createFramebuffers() {
719 | swapchainFramebuffers.resize(swapchainImageViews.size());
720 |
721 | for (size_t i = 0; i < swapchainImageViews.size(); i++) {
722 | VkImageView attachments[] = {
723 | swapchainImageViews[i]
724 | };
725 |
726 | VkFramebufferCreateInfo framebufferInfo = {};
727 | framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
728 | framebufferInfo.renderPass = renderPass;
729 | framebufferInfo.attachmentCount = 1;
730 | framebufferInfo.pAttachments = attachments;
731 | framebufferInfo.width = swapchainExtent.width;
732 | framebufferInfo.height = swapchainExtent.height;
733 | framebufferInfo.layers = 1;
734 |
735 | if (vkCreateFramebuffer(device, &framebufferInfo, nullptr, &swapchainFramebuffers[i])
736 | != VK_SUCCESS) {
737 | throw std::runtime_error("failed to create framebuffer!");
738 | }
739 | }
740 | }
741 |
742 | void VulkanTutorialApplication::createBuffer(VkDeviceSize size, VkBufferUsageFlags usage,
743 | VkMemoryPropertyFlags properties, VkBuffer &buffer,
744 | VkDeviceMemory &bufferMemory) {
745 | VkBufferCreateInfo bufferInfo = {
746 | .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
747 | .size = size,
748 | .usage = usage,
749 | .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
750 | };
751 | if (vkCreateBuffer(device, &bufferInfo, nullptr, &buffer) != VK_SUCCESS) {
752 | throw std::runtime_error("failed to create buffer!");
753 | }
754 |
755 | VkMemoryRequirements memRequirements;
756 | vkGetBufferMemoryRequirements(device, buffer, &memRequirements);
757 |
758 | VkMemoryAllocateInfo allocInfo = {
759 | .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
760 | .allocationSize = memRequirements.size,
761 | .memoryTypeIndex = findMemoryType(memRequirements.memoryTypeBits, properties),
762 | };
763 |
764 | if (vkAllocateMemory(device, &allocInfo, nullptr, &bufferMemory) != VK_SUCCESS) {
765 | throw std::runtime_error("failed to allocate buffer memory!");
766 | }
767 |
768 | vkBindBufferMemory(device, buffer, bufferMemory, 0);
769 | }
770 |
771 | void VulkanTutorialApplication::createImage(uint32_t width, uint32_t height, VkFormat format,
772 | VkImageTiling tiling, VkImageUsageFlags usage,
773 | VkMemoryPropertyFlags properties, VkImage &image,
774 | VkDeviceMemory &imageMemory) {
775 | VkImageCreateInfo imageInfo = {};
776 | imageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
777 | imageInfo.imageType = VK_IMAGE_TYPE_2D;
778 | imageInfo.extent.width = width;
779 | imageInfo.extent.height = height;
780 | imageInfo.extent.depth = 1;
781 | imageInfo.mipLevels = 1;
782 | imageInfo.arrayLayers = 1;
783 | imageInfo.format = format;
784 | imageInfo.tiling = tiling;
785 | imageInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
786 | imageInfo.usage = usage;
787 | imageInfo.samples = VK_SAMPLE_COUNT_1_BIT;
788 | imageInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
789 |
790 | if (vkCreateImage(device, &imageInfo, nullptr, &image) != VK_SUCCESS) {
791 | throw std::runtime_error("failed to create image!");
792 | }
793 |
794 | VkMemoryRequirements memRequirements;
795 | vkGetImageMemoryRequirements(device, image, &memRequirements);
796 |
797 | VkMemoryAllocateInfo allocInfo = {};
798 | allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
799 | allocInfo.allocationSize = memRequirements.size;
800 | allocInfo.memoryTypeIndex = findMemoryType(memRequirements.memoryTypeBits, properties);
801 |
802 | if (vkAllocateMemory(device, &allocInfo, nullptr, &imageMemory) != VK_SUCCESS) {
803 | throw std::runtime_error("failed to allocate image memory!");
804 | }
805 |
806 | vkBindImageMemory(device, image, imageMemory, 0);
807 | }
808 |
809 | void VulkanTutorialApplication::transitionImageLayout(VkImage image, VkFormat format,
810 | VkImageLayout oldLayout,
811 | VkImageLayout newLayout) {
812 | VkCommandBuffer commandBuffer = beginSingleTimeCommands();
813 |
814 | VkImageMemoryBarrier barrier = {};
815 | barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
816 | barrier.oldLayout = oldLayout;
817 | barrier.newLayout = newLayout;
818 | barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
819 | barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
820 | barrier.image = image;
821 | barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
822 | barrier.subresourceRange.baseMipLevel = 0;
823 | barrier.subresourceRange.levelCount = 1;
824 | barrier.subresourceRange.baseArrayLayer = 0;
825 | barrier.subresourceRange.layerCount = 1;
826 |
827 | VkPipelineStageFlags sourceStage;
828 | VkPipelineStageFlags destinationStage;
829 |
830 | if (oldLayout == VK_IMAGE_LAYOUT_UNDEFINED && newLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) {
831 | barrier.srcAccessMask = 0;
832 | barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
833 |
834 | sourceStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
835 | destinationStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
836 | } else if (oldLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL && newLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) {
837 | barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
838 | barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
839 |
840 | sourceStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
841 | destinationStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
842 | } else {
843 | throw std::invalid_argument("unsupported layout transition!");
844 | }
845 |
846 | vkCmdPipelineBarrier(
847 | commandBuffer,
848 | sourceStage, destinationStage,
849 | 0,
850 | 0, nullptr,
851 | 0, nullptr,
852 | 1, &barrier
853 | );
854 |
855 | endSingleTimeCommands(commandBuffer);
856 | }
857 |
858 | VkCommandBuffer VulkanTutorialApplication::beginSingleTimeCommands() {
859 | VkCommandBufferAllocateInfo allocInfo = {};
860 | allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
861 | allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
862 | allocInfo.commandPool = commandPool;
863 | allocInfo.commandBufferCount = 1;
864 |
865 | VkCommandBuffer commandBuffer;
866 | vkAllocateCommandBuffers(device, &allocInfo, &commandBuffer);
867 |
868 | VkCommandBufferBeginInfo beginInfo = {};
869 | beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
870 | beginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
871 |
872 | vkBeginCommandBuffer(commandBuffer, &beginInfo);
873 |
874 | return commandBuffer;
875 | }
876 |
877 | void VulkanTutorialApplication::endSingleTimeCommands(VkCommandBuffer commandBuffer) {
878 | vkEndCommandBuffer(commandBuffer);
879 |
880 | VkSubmitInfo submitInfo = {};
881 | submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
882 | submitInfo.commandBufferCount = 1;
883 | submitInfo.pCommandBuffers = &commandBuffer;
884 |
885 | vkQueueSubmit(graphicsQueue, 1, &submitInfo, VK_NULL_HANDLE);
886 | vkQueueWaitIdle(graphicsQueue);
887 |
888 | vkFreeCommandBuffers(device, commandPool, 1, &commandBuffer);
889 | }
890 |
891 | void VulkanTutorialApplication::copyBufferToImage(VkBuffer buffer, VkImage image, uint32_t width,
892 | uint32_t height) {
893 | VkCommandBuffer commandBuffer = beginSingleTimeCommands();
894 |
895 | VkBufferImageCopy region = {};
896 | region.bufferOffset = 0;
897 | region.bufferRowLength = 0;
898 | region.bufferImageHeight = 0;
899 | region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
900 | region.imageSubresource.mipLevel = 0;
901 | region.imageSubresource.baseArrayLayer = 0;
902 | region.imageSubresource.layerCount = 1;
903 | region.imageOffset = {0, 0, 0};
904 | region.imageExtent = {
905 | width,
906 | height,
907 | 1
908 | };
909 |
910 | vkCmdCopyBufferToImage(commandBuffer, buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion);
911 |
912 | endSingleTimeCommands(commandBuffer);
913 | }
914 |
915 | VkImageView VulkanTutorialApplication::createImageView(VkImage image, VkFormat format) {
916 | VkImageViewCreateInfo viewInfo = {};
917 | viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
918 | viewInfo.image = image;
919 | viewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
920 | viewInfo.format = format;
921 | viewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
922 | viewInfo.subresourceRange.baseMipLevel = 0;
923 | viewInfo.subresourceRange.levelCount = 1;
924 | viewInfo.subresourceRange.baseArrayLayer = 0;
925 | viewInfo.subresourceRange.layerCount = 1;
926 |
927 | VkImageView imageView;
928 | if (vkCreateImageView(device, &viewInfo, nullptr, &imageView) != VK_SUCCESS) {
929 | throw std::runtime_error("failed to create texture image view!");
930 | }
931 |
932 | return imageView;
933 | }
934 |
935 | void VulkanTutorialApplication::createTextureImage() {
936 | AAsset* file = AAssetManager_open(assetManager, IMAGE_PATH.c_str(), AASSET_MODE_BUFFER);
937 | size_t fileLength = AAsset_getLength(file);
938 | stbi_uc* fileContent = new unsigned char[fileLength];
939 | AAsset_read(file, fileContent, fileLength);
940 |
941 | int texWidth, texHeight, texChannels;
942 | stbi_uc* pixels = stbi_load_from_memory(fileContent,fileLength,&texWidth,&texHeight,&texChannels,STBI_rgb_alpha);
943 | VkDeviceSize imageSize = texWidth * texHeight * 4;
944 |
945 | if (!pixels) {
946 | throw std::runtime_error("failed to load texture image!");
947 | }
948 |
949 | VkBuffer stagingBuffer;
950 | VkDeviceMemory stagingBufferMemory;
951 | createBuffer(imageSize,VK_BUFFER_USAGE_TRANSFER_SRC_BIT,VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
952 | stagingBuffer,stagingBufferMemory);
953 |
954 | void* data;
955 | vkMapMemory(device,stagingBufferMemory,0,imageSize,0,&data);
956 | memcpy(data,pixels, static_cast(imageSize));
957 | vkUnmapMemory(device,stagingBufferMemory);
958 |
959 | stbi_image_free(pixels);
960 |
961 | createImage(texWidth, texHeight, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
962 | VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, textureImage, textureImageMemory);
963 | transitionImageLayout(textureImage,VK_FORMAT_R8G8B8A8_UNORM,VK_IMAGE_LAYOUT_UNDEFINED,VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
964 | copyBufferToImage(stagingBuffer, textureImage, static_cast(texWidth), static_cast(texHeight));
965 | transitionImageLayout(textureImage, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
966 |
967 | vkDestroyBuffer(device, stagingBuffer, nullptr);
968 | vkFreeMemory(device, stagingBufferMemory, nullptr);
969 | }
970 |
971 | void VulkanTutorialApplication::createTextureImageView() {
972 | textureImageView = createImageView(textureImage, VK_FORMAT_R8G8B8A8_UNORM);
973 | }
974 |
975 | void VulkanTutorialApplication::createTextureSampler() {
976 | VkSamplerCreateInfo samplerInfo = {};
977 | samplerInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
978 | samplerInfo.magFilter = VK_FILTER_LINEAR;
979 | samplerInfo.minFilter = VK_FILTER_LINEAR;
980 | samplerInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT;
981 | samplerInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT;
982 | samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT;
983 | samplerInfo.anisotropyEnable = VK_TRUE;
984 | samplerInfo.maxAnisotropy = 16;
985 | samplerInfo.borderColor = VK_BORDER_COLOR_INT_OPAQUE_BLACK;
986 | samplerInfo.unnormalizedCoordinates = VK_FALSE;
987 | samplerInfo.compareEnable = VK_FALSE;
988 | samplerInfo.compareOp = VK_COMPARE_OP_ALWAYS;
989 | samplerInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
990 |
991 | if (vkCreateSampler(device, &samplerInfo, nullptr, &textureSampler) != VK_SUCCESS) {
992 | throw std::runtime_error("failed to create texture sampler!");
993 | }
994 | }
995 |
996 | void VulkanTutorialApplication::createVertexBuffer() {
997 | VkDeviceSize bufferSize = sizeof(vertices[0]) * vertices.size();
998 |
999 | VkBuffer stagingBuffer;
1000 | VkDeviceMemory stagingBufferMemory;
1001 | createBuffer(bufferSize,
1002 | VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
1003 | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
1004 | stagingBuffer,
1005 | stagingBufferMemory);
1006 |
1007 | void *data;
1008 | vkMapMemory(device, stagingBufferMemory, 0, bufferSize, 0, &data);
1009 | memcpy(data, vertices.data(), (size_t) bufferSize);
1010 | vkUnmapMemory(device, stagingBufferMemory);
1011 |
1012 | createBuffer(bufferSize,
1013 | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
1014 | VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
1015 | vertexBuffer,
1016 | vertexBufferMemory);
1017 |
1018 | copyBuffer(stagingBuffer, vertexBuffer, bufferSize);
1019 |
1020 | vkDestroyBuffer(device, stagingBuffer, nullptr);
1021 | vkFreeMemory(device, stagingBufferMemory, nullptr);
1022 | }
1023 |
1024 | void VulkanTutorialApplication::createIndexBuffer() {
1025 | VkDeviceSize bufferSize = sizeof(indices[0]) * indices.size();
1026 |
1027 | VkBuffer stagingBuffer;
1028 | VkDeviceMemory stagingBufferMemory;
1029 | createBuffer(bufferSize,
1030 | VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
1031 | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
1032 | stagingBuffer,
1033 | stagingBufferMemory);
1034 |
1035 | void *data;
1036 | vkMapMemory(device, stagingBufferMemory, 0, bufferSize, 0, &data);
1037 | memcpy(data, indices.data(), (size_t) bufferSize);
1038 | vkUnmapMemory(device, stagingBufferMemory);
1039 |
1040 | createBuffer(bufferSize,
1041 | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
1042 | VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
1043 | indexBuffer,
1044 | indexBufferMemory);
1045 |
1046 | copyBuffer(stagingBuffer, indexBuffer, bufferSize);
1047 |
1048 | vkDestroyBuffer(device, stagingBuffer, nullptr);
1049 | vkFreeMemory(device, stagingBufferMemory, nullptr);
1050 | }
1051 |
1052 | void VulkanTutorialApplication::createUniformBuffer() {
1053 | VkDeviceSize bufferSize = sizeof(UniformBufferObject);
1054 | createBuffer(bufferSize,
1055 | VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
1056 | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
1057 | uniformBuffer,
1058 | uniformBufferMemory);
1059 | }
1060 |
1061 | void VulkanTutorialApplication::createDescriptorPool() {
1062 | std::array poolSizes = {};
1063 | poolSizes[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
1064 | poolSizes[0].descriptorCount = 1;
1065 | poolSizes[1].type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
1066 | poolSizes[1].descriptorCount = 1;
1067 |
1068 | VkDescriptorPoolCreateInfo poolInfo = {
1069 | .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1070 | .poolSizeCount = static_cast(poolSizes.size()),
1071 | .pPoolSizes = poolSizes.data(),
1072 | .maxSets = 1,
1073 | };
1074 | if (vkCreateDescriptorPool(device, &poolInfo, nullptr, &descriptorPool) != VK_SUCCESS) {
1075 | throw std::runtime_error("failed to create descriptor pool!");
1076 | }
1077 | }
1078 |
1079 | void VulkanTutorialApplication::createDescriptorSet() {
1080 | VkDescriptorSetLayout layouts[] = {descriptorSetLayout};
1081 | VkDescriptorSetAllocateInfo allocInfo = {
1082 | .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
1083 | .descriptorPool = descriptorPool,
1084 | .descriptorSetCount = 1,
1085 | .pSetLayouts = layouts,
1086 | };
1087 | if (vkAllocateDescriptorSets(device, &allocInfo, &descriptorSet) != VK_SUCCESS) {
1088 | throw std::runtime_error("failed to allocate descriptor set!");
1089 | }
1090 |
1091 | VkDescriptorBufferInfo bufferInfo = {
1092 | .buffer = uniformBuffer,
1093 | .offset = 0,
1094 | .range = sizeof(UniformBufferObject),
1095 | };
1096 |
1097 | VkDescriptorImageInfo imageInfo = {
1098 | .imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
1099 | .imageView = textureImageView,
1100 | .sampler = textureSampler,
1101 | };
1102 |
1103 | std::array descriptorWrites = {};
1104 |
1105 | descriptorWrites[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
1106 | descriptorWrites[0].dstSet = descriptorSet;
1107 | descriptorWrites[0].dstBinding = 0;
1108 | descriptorWrites[0].dstArrayElement = 0;
1109 | descriptorWrites[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
1110 | descriptorWrites[0].descriptorCount = 1;
1111 | descriptorWrites[0].pBufferInfo = &bufferInfo;
1112 |
1113 | descriptorWrites[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
1114 | descriptorWrites[1].dstSet = descriptorSet;
1115 | descriptorWrites[1].dstBinding = 1;
1116 | descriptorWrites[1].dstArrayElement = 0;
1117 | descriptorWrites[1].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
1118 | descriptorWrites[1].descriptorCount = 1;
1119 | descriptorWrites[1].pImageInfo = &imageInfo;
1120 |
1121 | vkUpdateDescriptorSets(device, static_cast(descriptorWrites.size()), descriptorWrites.data(), 0, nullptr);
1122 | }
1123 |
1124 | void VulkanTutorialApplication::copyBuffer(
1125 | VkBuffer srcBuffer, VkBuffer dstBuffer, VkDeviceSize size) {
1126 | VkCommandBufferAllocateInfo allocInfo = {
1127 | .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
1128 | .level = VK_COMMAND_BUFFER_LEVEL_PRIMARY,
1129 | .commandPool = commandPool,
1130 | .commandBufferCount = 1,
1131 | };
1132 |
1133 | VkCommandBuffer commandBuffer;
1134 | vkAllocateCommandBuffers(device, &allocInfo, &commandBuffer);
1135 |
1136 | VkCommandBufferBeginInfo beginInfo = {
1137 | .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
1138 | .flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,
1139 | };
1140 | vkBeginCommandBuffer(commandBuffer, &beginInfo);
1141 |
1142 | VkBufferCopy copyRegion = {
1143 | .size = size
1144 | };
1145 | vkCmdCopyBuffer(commandBuffer, srcBuffer, dstBuffer, 1, ©Region);
1146 |
1147 | vkEndCommandBuffer(commandBuffer);
1148 |
1149 | VkSubmitInfo submitInfo = {
1150 | .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
1151 | .commandBufferCount = 1,
1152 | .pCommandBuffers = &commandBuffer,
1153 | };
1154 | vkQueueSubmit(graphicsQueue, 1, &submitInfo, VK_NULL_HANDLE);
1155 | vkQueueWaitIdle(graphicsQueue);
1156 |
1157 | vkFreeCommandBuffers(device, commandPool, 1, &commandBuffer);
1158 | }
1159 |
1160 | uint32_t VulkanTutorialApplication::findMemoryType(
1161 | uint32_t typeFilter, VkMemoryPropertyFlags properties) {
1162 | VkPhysicalDeviceMemoryProperties memProperties;
1163 | vkGetPhysicalDeviceMemoryProperties(physicalDevice, &memProperties);
1164 |
1165 | for (uint32_t i = 0; i < memProperties.memoryTypeCount; i++) {
1166 | if ((typeFilter & (1 << i))
1167 | && (memProperties.memoryTypes[i].propertyFlags & properties) == properties) {
1168 | return i;
1169 | }
1170 | }
1171 |
1172 | throw std::runtime_error("failed to find suitable memory type!");
1173 | }
1174 |
1175 | void VulkanTutorialApplication::createCommandBuffers() {
1176 | commandBuffers.resize(swapchainFramebuffers.size());
1177 |
1178 | VkCommandBufferAllocateInfo allocInfo = {};
1179 | allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
1180 | allocInfo.commandPool = commandPool;
1181 | allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
1182 | allocInfo.commandBufferCount = (uint32_t) commandBuffers.size();
1183 |
1184 | if (vkAllocateCommandBuffers(device, &allocInfo, commandBuffers.data()) != VK_SUCCESS) {
1185 | throw std::runtime_error("failed to allocate command buffers!");
1186 | }
1187 |
1188 | for (size_t i = 0; i < commandBuffers.size(); i++) {
1189 | VkCommandBufferBeginInfo beginInfo = {};
1190 | beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
1191 | beginInfo.flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT;
1192 | beginInfo.pInheritanceInfo = nullptr; // Optional
1193 |
1194 | vkBeginCommandBuffer(commandBuffers[i], &beginInfo);
1195 |
1196 | VkRenderPassBeginInfo renderPassInfo = {};
1197 | renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
1198 | renderPassInfo.renderPass = renderPass;
1199 | renderPassInfo.framebuffer = swapchainFramebuffers[i];
1200 | renderPassInfo.renderArea.offset = {0, 0};
1201 | renderPassInfo.renderArea.extent = swapchainExtent;
1202 |
1203 | VkClearValue clearColor = {0.0f, 0.0f, 0.0f, 1.0f};
1204 | renderPassInfo.clearValueCount = 1;
1205 | renderPassInfo.pClearValues = &clearColor;
1206 |
1207 | vkCmdBeginRenderPass(commandBuffers[i], &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE);
1208 |
1209 | vkCmdBindPipeline(commandBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline);
1210 |
1211 | VkBuffer vertexBuffers[] = {vertexBuffer};
1212 | VkDeviceSize offsets[] = {0};
1213 | vkCmdBindVertexBuffers(commandBuffers[i], 0, 1, vertexBuffers, offsets);
1214 |
1215 | vkCmdBindIndexBuffer(commandBuffers[i], indexBuffer, 0, VK_INDEX_TYPE_UINT16);
1216 |
1217 | vkCmdBindDescriptorSets(commandBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout,
1218 | 0, 1, &descriptorSet, 0, nullptr);
1219 |
1220 | vkCmdDrawIndexed(commandBuffers[i], static_cast(indices.size()), 1, 0, 0, 0);
1221 |
1222 | vkCmdEndRenderPass(commandBuffers[i]);
1223 |
1224 | if (vkEndCommandBuffer(commandBuffers[i]) != VK_SUCCESS) {
1225 | throw std::runtime_error("failed to record command buffer!");
1226 | }
1227 | }
1228 | }
1229 |
1230 | void VulkanTutorialApplication::createSemaphores() {
1231 | VkSemaphoreCreateInfo semaphoreInfo = {};
1232 | semaphoreInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
1233 |
1234 | if (vkCreateSemaphore(device, &semaphoreInfo, nullptr, &imageAvailableSemaphore) != VK_SUCCESS
1235 | || vkCreateSemaphore(device, &semaphoreInfo, nullptr, &renderFinishedSemaphore)
1236 | != VK_SUCCESS) {
1237 | throw std::runtime_error("failed to create semaphores!");
1238 | }
1239 | }
1240 |
1241 | void VulkanTutorialApplication::updateUniformBuffer() {
1242 | static auto startTime = std::chrono::high_resolution_clock::now();
1243 |
1244 | auto currentTime = std::chrono::high_resolution_clock::now();
1245 | float time =
1246 | std::chrono::duration_cast(currentTime - startTime).count()
1247 | / 1e3f;
1248 |
1249 | UniformBufferObject ubo = {
1250 | .model = glm::rotate(glm::mat4(), time * glm::radians(90.0f),
1251 | glm::vec3(0.0f, 0.0f, 1.0f)),
1252 | .view = glm::lookAt(glm::vec3(2.0f, 2.0f, 2.0f), glm::vec3(0.0f, 0.0f, 0.0f),
1253 | glm::vec3(0.0f, 0.0f, 1.0f)),
1254 | .proj = glm::perspective(glm::radians(45.0f),
1255 | swapchainExtent.width / (float) swapchainExtent.height, 0.1f,
1256 | 10.0f),
1257 | };
1258 | ubo.proj[1][1] *= -1;
1259 |
1260 | void *data;
1261 | vkMapMemory(device, uniformBufferMemory, 0, sizeof(ubo), 0, &data);
1262 | memcpy(data, &ubo, sizeof(ubo));
1263 | vkUnmapMemory(device, uniformBufferMemory);
1264 | }
1265 |
1266 | void VulkanTutorialApplication::drawFrame() {
1267 | uint32_t imageIndex = 0;
1268 | VkResult result = vkAcquireNextImageKHR(device, swapchain, std::numeric_limits::max(),
1269 | imageAvailableSemaphore, VK_NULL_HANDLE, &imageIndex);
1270 |
1271 | if (result == VK_ERROR_OUT_OF_DATE_KHR) {
1272 | recreateSwapchain();
1273 | return;
1274 | } else if (result != VK_SUCCESS && result != VK_SUBOPTIMAL_KHR) {
1275 | throw std::runtime_error("failed to acquire swap chain image!");
1276 | }
1277 |
1278 | VkSubmitInfo submitInfo = {};
1279 | submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
1280 |
1281 | VkSemaphore waitSemaphores[] = {imageAvailableSemaphore};
1282 | VkPipelineStageFlags waitStages[] = {VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT};
1283 | submitInfo.waitSemaphoreCount = 1;
1284 | submitInfo.pWaitSemaphores = waitSemaphores;
1285 | submitInfo.pWaitDstStageMask = waitStages;
1286 | submitInfo.commandBufferCount = 1;
1287 | submitInfo.pCommandBuffers = &commandBuffers[imageIndex];
1288 |
1289 | VkSemaphore signalSemaphores[] = {renderFinishedSemaphore};
1290 | submitInfo.signalSemaphoreCount = 1;
1291 | submitInfo.pSignalSemaphores = signalSemaphores;
1292 |
1293 | if (vkQueueSubmit(graphicsQueue, 1, &submitInfo, VK_NULL_HANDLE) != VK_SUCCESS) {
1294 | throw std::runtime_error("failed to submit draw command buffer!");
1295 | }
1296 |
1297 | VkPresentInfoKHR presentInfo = {};
1298 | presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
1299 |
1300 | presentInfo.waitSemaphoreCount = 1;
1301 | presentInfo.pWaitSemaphores = signalSemaphores;
1302 |
1303 | VkSwapchainKHR swapChains[] = {swapchain};
1304 | presentInfo.swapchainCount = 1;
1305 | presentInfo.pSwapchains = swapChains;
1306 |
1307 | presentInfo.pImageIndices = &imageIndex;
1308 |
1309 | result = vkQueuePresentKHR(presentQueue, &presentInfo);
1310 |
1311 | if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR) {
1312 | recreateSwapchain();
1313 | } else if (result != VK_SUCCESS) {
1314 | throw std::runtime_error("failed to present swap chain image!");
1315 | }
1316 |
1317 | vkQueueWaitIdle(presentQueue);
1318 | }
1319 |
1320 | void VulkanTutorialApplication::recreateSwapchain() {
1321 | LOGI("recreateSwapchain");
1322 |
1323 | vkDeviceWaitIdle(device);
1324 |
1325 | cleanupSwapchain();
1326 |
1327 | createSwapchain();
1328 | createImageViews();
1329 | createRenderPass();
1330 | createGraphicsPipeline();
1331 | createFramebuffers();
1332 | createCommandBuffers();
1333 | }
1334 |
1335 | void VulkanTutorialApplication::cleanupSwapchain() {
1336 | for (size_t i = 0; i < swapchainFramebuffers.size(); i++) {
1337 | vkDestroyFramebuffer(device, swapchainFramebuffers[i], nullptr);
1338 | }
1339 |
1340 | vkFreeCommandBuffers(device, commandPool, static_cast(commandBuffers.size()),
1341 | commandBuffers.data());
1342 |
1343 | vkDestroyPipeline(device, graphicsPipeline, nullptr);
1344 | vkDestroyPipelineLayout(device, pipelineLayout, nullptr);
1345 | vkDestroyRenderPass(device, renderPass, nullptr);
1346 |
1347 | for (size_t i = 0; i < swapchainImageViews.size(); i++) {
1348 | vkDestroyImageView(device, swapchainImageViews[i], nullptr);
1349 | }
1350 |
1351 | vkDestroySwapchainKHR(device, swapchain, nullptr);
1352 | }
1353 |
1354 | std::vector VulkanTutorialApplication::readAsset(std::string name) {
1355 | AAsset *file = AAssetManager_open(assetManager, name.c_str(), AASSET_MODE_BUFFER);
1356 | size_t len = AAsset_getLength(file);
1357 | std::vector buffer(len);
1358 |
1359 | AAsset_read(file, buffer.data(), len);
1360 |
1361 | AAsset_close(file);
1362 |
1363 | LOGI("read asset %s, length %d", name.c_str(), len);
1364 |
1365 | return buffer;
1366 | }
1367 |
1368 | void VulkanTutorialApplication::createCommandPool() {
1369 | QueueFamilyIndices queueFamilyIndices = findQueueFamilies(physicalDevice);
1370 |
1371 | VkCommandPoolCreateInfo poolInfo = {};
1372 | poolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
1373 | poolInfo.queueFamilyIndex = queueFamilyIndices.graphicsFamily;
1374 | poolInfo.flags = 0; // Optional
1375 |
1376 | if (vkCreateCommandPool(device, &poolInfo, nullptr, &commandPool) != VK_SUCCESS) {
1377 | throw std::runtime_error("failed to create command pool!");
1378 | }
1379 | }
1380 |
1381 | VkShaderModule VulkanTutorialApplication::createShaderModule(const std::vector &code) {
1382 | VkShaderModuleCreateInfo createInfo = {};
1383 | createInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
1384 | createInfo.codeSize = code.size();
1385 | createInfo.pCode = reinterpret_cast(code.data());
1386 |
1387 | VkShaderModule shaderModule;
1388 | if (vkCreateShaderModule(device, &createInfo, nullptr, &shaderModule) != VK_SUCCESS) {
1389 | throw std::runtime_error("failed to create shader module!");
1390 | }
1391 |
1392 | return shaderModule;
1393 | }
1394 |
1395 | bool VulkanTutorialApplication::isDeviceSuitable(VkPhysicalDevice device) {
1396 | bool extensionsSupported = checkDeviceExtensionSupport(device);
1397 |
1398 | bool swapchainAdequate = false;
1399 | if (extensionsSupported) {
1400 | SwapchainSupportDetails swapChainSupport = querySwapchainSupport(device);
1401 | swapchainAdequate =
1402 | !swapChainSupport.formats.empty() && !swapChainSupport.presentModes.empty();
1403 | }
1404 |
1405 | QueueFamilyIndices indices = findQueueFamilies(device);
1406 |
1407 | return indices.isComplete() && extensionsSupported && swapchainAdequate;
1408 | }
1409 |
1410 |
1411 | bool VulkanTutorialApplication::checkDeviceExtensionSupport(VkPhysicalDevice device) {
1412 | uint32_t extensionCount = 0;
1413 | vkEnumerateDeviceExtensionProperties(device, nullptr, &extensionCount, nullptr);
1414 |
1415 | std::vector availableExtensions(extensionCount);
1416 | vkEnumerateDeviceExtensionProperties(device, nullptr, &extensionCount,
1417 | availableExtensions.data());
1418 |
1419 | std::set requiredExtensions(deviceExtensions.begin(), deviceExtensions.end());
1420 |
1421 | for (const auto &extension : availableExtensions) {
1422 | requiredExtensions.erase(extension.extensionName);
1423 | }
1424 |
1425 | return requiredExtensions.empty();
1426 | }
1427 |
1428 | VulkanTutorialApplication::QueueFamilyIndices
1429 | VulkanTutorialApplication::findQueueFamilies(VkPhysicalDevice device) {
1430 | QueueFamilyIndices indices;
1431 |
1432 | uint32_t queueFamilyCount = 0;
1433 | vkGetPhysicalDeviceQueueFamilyProperties(device, &queueFamilyCount, nullptr);
1434 |
1435 | std::vector queueFamilies(queueFamilyCount);
1436 | vkGetPhysicalDeviceQueueFamilyProperties(device, &queueFamilyCount, queueFamilies.data());
1437 |
1438 | int i = 0;
1439 | for (const auto &queueFamily : queueFamilies) {
1440 | if (queueFamily.queueCount > 0 && queueFamily.queueFlags & VK_QUEUE_GRAPHICS_BIT) {
1441 | indices.graphicsFamily = i;
1442 | }
1443 |
1444 | VkBool32 presentSupport = false;
1445 | vkGetPhysicalDeviceSurfaceSupportKHR(device, i, surface, &presentSupport);
1446 | if (queueFamily.queueCount > 0 && presentSupport) {
1447 | indices.presentFamily = i;
1448 | }
1449 |
1450 | if (indices.isComplete()) {
1451 | break;
1452 | }
1453 |
1454 | i++;
1455 | }
1456 |
1457 | return indices;
1458 | }
1459 |
1460 | VulkanTutorialApplication::SwapchainSupportDetails
1461 | VulkanTutorialApplication::querySwapchainSupport(VkPhysicalDevice device) {
1462 | SwapchainSupportDetails details;
1463 |
1464 | vkGetPhysicalDeviceSurfaceCapabilitiesKHR(device, surface, &details.capabilities);
1465 |
1466 | uint32_t formatCount = 0;
1467 | vkGetPhysicalDeviceSurfaceFormatsKHR(device, surface, &formatCount, nullptr);
1468 | if (formatCount > 0) {
1469 | details.formats.resize(formatCount);
1470 | vkGetPhysicalDeviceSurfaceFormatsKHR(device, surface, &formatCount,
1471 | details.formats.data());
1472 | }
1473 |
1474 | uint32_t presentModeCount = 0;
1475 | vkGetPhysicalDeviceSurfacePresentModesKHR(device, surface, &presentModeCount, nullptr);
1476 | if (presentModeCount > 0) {
1477 | details.presentModes.resize(presentModeCount);
1478 | vkGetPhysicalDeviceSurfacePresentModesKHR(device, surface, &presentModeCount,
1479 | details.presentModes.data());
1480 | }
1481 |
1482 | return details;
1483 | }
1484 |
--------------------------------------------------------------------------------
/app/src/main/cpp/vulkan_tutorial.h:
--------------------------------------------------------------------------------
1 | //
2 | // Created by Piasy on 29/06/2017.
3 | //
4 |
5 | #ifndef VULKANTUTORIAL_ANDROID_VULKAN_TRIANGLE_H
6 | #define VULKANTUTORIAL_ANDROID_VULKAN_TRIANGLE_H
7 |
8 | #include
9 | #include
10 |
11 | #include
12 | #include
13 | #include
14 |
15 | #include
16 | #include
17 |
18 | #define APP_NAME "VK-TUTORIAL"
19 | #define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, APP_NAME, __VA_ARGS__))
20 | #define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, APP_NAME, __VA_ARGS__))
21 |
22 | #define STATE_RUNNING 1
23 | #define STATE_PAUSED 2
24 | #define STATE_EXIT 3
25 |
26 | class VulkanTutorialApplication {
27 | public:
28 | struct QueueFamilyIndices {
29 | int graphicsFamily = -1;
30 | int presentFamily = -1;
31 |
32 | bool isComplete() {
33 | return graphicsFamily >= 0 && presentFamily >= 0;
34 | }
35 | };
36 |
37 | struct SwapchainSupportDetails {
38 | VkSurfaceCapabilitiesKHR capabilities;
39 | std::vector formats;
40 | std::vector presentModes;
41 | };
42 |
43 | struct Vertex {
44 | glm::vec2 pos;
45 | glm::vec3 color;
46 | glm::vec2 texCoord;
47 |
48 | static VkVertexInputBindingDescription getBindingDescription() {
49 | VkVertexInputBindingDescription bindingDescription = {};
50 | bindingDescription.binding = 0;
51 | bindingDescription.stride = sizeof(Vertex);
52 | bindingDescription.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
53 |
54 | return bindingDescription;
55 | }
56 |
57 | static std::array getAttributeDescriptions() {
58 | std::array attributeDescriptions = {};
59 |
60 | attributeDescriptions[0].binding = 0;
61 | attributeDescriptions[0].location = 0;
62 | attributeDescriptions[0].format = VK_FORMAT_R32G32_SFLOAT;
63 | attributeDescriptions[0].offset = offsetof(Vertex, pos);
64 |
65 | attributeDescriptions[1].binding = 0;
66 | attributeDescriptions[1].location = 1;
67 | attributeDescriptions[1].format = VK_FORMAT_R32G32B32_SFLOAT;
68 | attributeDescriptions[1].offset = offsetof(Vertex, color);
69 |
70 | attributeDescriptions[2].binding = 0;
71 | attributeDescriptions[2].location = 2;
72 | attributeDescriptions[2].format = VK_FORMAT_R32G32_SFLOAT;
73 | attributeDescriptions[2].offset = offsetof(Vertex, texCoord);
74 |
75 | return attributeDescriptions;
76 | }
77 | };
78 |
79 | struct UniformBufferObject {
80 | glm::mat4 model;
81 | glm::mat4 view;
82 | glm::mat4 proj;
83 | };
84 |
85 | VulkanTutorialApplication(
86 | AAssetManager *assetManager,
87 | const char *vertexShader,
88 | const char *fragmentShader) :
89 | assetManager(assetManager),
90 | vertexShader(std::string(vertexShader)),
91 | fragmentShader(std::string(fragmentShader)),
92 | state(STATE_RUNNING) {
93 | }
94 |
95 | void run(ANativeWindow *window);
96 |
97 | void pause();
98 |
99 | inline void resume() {
100 | state = STATE_RUNNING;
101 | }
102 |
103 | void surfaceChanged();
104 |
105 | inline void stop() {
106 | state = STATE_EXIT;
107 | }
108 |
109 | private:
110 | inline void initWindow(ANativeWindow *window) {
111 | this->window = window;
112 | }
113 |
114 | void initVulkan();
115 |
116 | void mainLoop();
117 |
118 | void cleanUp();
119 |
120 | void createInstance();
121 |
122 | void setUpDebugCallback();
123 |
124 | void createSurface();
125 |
126 | void pickPhysicalDevice();
127 |
128 | void createLogicalDevice();
129 |
130 | void createSwapchain();
131 |
132 | void createImageViews();
133 |
134 | void createRenderPass();
135 |
136 | void createDescriptorSetLayout();
137 |
138 | void createGraphicsPipeline();
139 |
140 | void createFramebuffers();
141 |
142 | void createBuffer(VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags properties,
143 | VkBuffer &buffer, VkDeviceMemory &bufferMemory);
144 |
145 | void createImage(uint32_t width, uint32_t height, VkFormat format, VkImageTiling tiling,
146 | VkImageUsageFlags usage, VkMemoryPropertyFlags properties, VkImage& image, VkDeviceMemory& imageMemory);
147 |
148 | void transitionImageLayout(VkImage image, VkFormat format, VkImageLayout oldLayout, VkImageLayout newLayout);
149 |
150 | VkCommandBuffer beginSingleTimeCommands();
151 |
152 | void endSingleTimeCommands(VkCommandBuffer commandBuffer);
153 |
154 | void copyBufferToImage(VkBuffer buffer, VkImage image, uint32_t width, uint32_t height);
155 |
156 | VkImageView createImageView(VkImage image, VkFormat format);
157 |
158 | void createCommandPool();
159 |
160 | void createTextureImage();
161 |
162 | void createTextureSampler();
163 |
164 | void createTextureImageView();
165 |
166 | void createVertexBuffer();
167 |
168 | void createIndexBuffer();
169 |
170 | void createUniformBuffer();
171 |
172 | void createDescriptorPool();
173 |
174 | void createDescriptorSet();
175 |
176 | void copyBuffer(VkBuffer srcBuffer, VkBuffer dstBuffer, VkDeviceSize size);
177 |
178 | uint32_t findMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags properties);
179 |
180 | void createCommandBuffers();
181 |
182 | void createSemaphores();
183 |
184 | void updateUniformBuffer();
185 |
186 | void drawFrame();
187 |
188 | void recreateSwapchain();
189 |
190 | void cleanupSwapchain();
191 |
192 | std::vector readAsset(std::string name);
193 |
194 | VkShaderModule createShaderModule(const std::vector &code);
195 |
196 | bool isDeviceSuitable(VkPhysicalDevice device);
197 |
198 | bool checkDeviceExtensionSupport(VkPhysicalDevice device);
199 |
200 | QueueFamilyIndices findQueueFamilies(VkPhysicalDevice device);
201 |
202 | SwapchainSupportDetails querySwapchainSupport(VkPhysicalDevice device);
203 |
204 | AAssetManager *assetManager;
205 | std::string vertexShader;
206 | std::string fragmentShader;
207 | int state;
208 |
209 | VkInstance instance;
210 | VkDebugReportCallbackEXT callback;
211 | ANativeWindow *window;
212 | VkSurfaceKHR surface;
213 |
214 | VkPhysicalDevice physicalDevice = VK_NULL_HANDLE;
215 | VkDevice device;
216 |
217 | VkQueue graphicsQueue;
218 | VkQueue presentQueue;
219 |
220 | VkSwapchainKHR swapchain;
221 | VkRenderPass renderPass;
222 | VkDescriptorSetLayout descriptorSetLayout;
223 | VkDescriptorPool descriptorPool;
224 | VkDescriptorSet descriptorSet;
225 | VkPipelineLayout pipelineLayout;
226 | VkPipeline graphicsPipeline;
227 | VkCommandPool commandPool;
228 |
229 | VkFormat swapchainImageFormat;
230 | VkExtent2D swapchainExtent;
231 | std::vector swapchainImages;
232 | std::vector swapchainImageViews;
233 | std::vector swapchainFramebuffers;
234 | std::vector commandBuffers;
235 |
236 | VkBuffer vertexBuffer;
237 | VkDeviceMemory vertexBufferMemory;
238 | VkBuffer indexBuffer;
239 | VkDeviceMemory indexBufferMemory;
240 | VkBuffer uniformBuffer;
241 | VkDeviceMemory uniformBufferMemory;
242 |
243 | VkImage textureImage;
244 | VkDeviceMemory textureImageMemory;
245 | VkImageView textureImageView;
246 | VkSampler textureSampler;
247 |
248 | VkSemaphore imageAvailableSemaphore;
249 | VkSemaphore renderFinishedSemaphore;
250 | };
251 |
252 | #endif //VULKANTUTORIAL_ANDROID_VULKAN_TRIANGLE_H
253 |
--------------------------------------------------------------------------------
/app/src/main/cpp/vulkan_tutorial_jni.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // Created by Piasy on 29/06/2017.
3 | //
4 |
5 | #include
6 | #include
7 | #include
8 |
9 | #include "vulkan_tutorial.h"
10 |
11 | extern "C" {
12 |
13 | JNIEXPORT jlong JNICALL
14 | Java_com_github_piasy_vulkantutorial_VulkanTutorialApplication_create(
15 | JNIEnv *env, jclass type, jobject assetManager_, jstring vertexShader_,
16 | jstring fragmentShader_) {
17 |
18 | AAssetManager *assetManager = AAssetManager_fromJava(env, assetManager_);
19 | if (assetManager == nullptr) {
20 | LOGE("get assetManager fail!");
21 | return 0;
22 | }
23 |
24 | const char *vertexShader = env->GetStringUTFChars(vertexShader_, 0);
25 | const char *fragmentShader = env->GetStringUTFChars(fragmentShader_, 0);
26 |
27 | VulkanTutorialApplication *app = new VulkanTutorialApplication(assetManager, vertexShader,
28 | fragmentShader);
29 |
30 | env->ReleaseStringUTFChars(vertexShader_, vertexShader);
31 | env->ReleaseStringUTFChars(fragmentShader_, fragmentShader);
32 |
33 | return (jlong) app;
34 | }
35 |
36 | JNIEXPORT void JNICALL
37 | Java_com_github_piasy_vulkantutorial_VulkanTutorialApplication_run__JLandroid_view_Surface_2(
38 | JNIEnv *env, jclass type, jlong nativeHandle, jobject surface) {
39 | ANativeWindow *window = ANativeWindow_fromSurface(env, surface);
40 | if (window == nullptr) {
41 | LOGE("get window from surface fail!");
42 | return;
43 | }
44 |
45 | VulkanTutorialApplication *app = reinterpret_cast(nativeHandle);
46 | app->run(window);
47 | }
48 |
49 | JNIEXPORT void JNICALL
50 | Java_com_github_piasy_vulkantutorial_VulkanTutorialApplication_pause__J(JNIEnv *env, jclass type,
51 | jlong nativeHandle) {
52 | VulkanTutorialApplication *app = reinterpret_cast(nativeHandle);
53 | app->pause();
54 | }
55 |
56 | JNIEXPORT void JNICALL
57 | Java_com_github_piasy_vulkantutorial_VulkanTutorialApplication_resume__J(JNIEnv *env, jclass type,
58 | jlong nativeHandle) {
59 | VulkanTutorialApplication *app = reinterpret_cast(nativeHandle);
60 | app->resume();
61 | }
62 |
63 | JNIEXPORT void JNICALL
64 | Java_com_github_piasy_vulkantutorial_VulkanTutorialApplication_surfaceChanged__J(
65 | JNIEnv *env, jclass type, jlong nativeHandle) {
66 | VulkanTutorialApplication *app = reinterpret_cast(nativeHandle);
67 | app->surfaceChanged();
68 | }
69 |
70 | JNIEXPORT void JNICALL
71 | Java_com_github_piasy_vulkantutorial_VulkanTutorialApplication_stop__J(JNIEnv *env, jclass type,
72 | jlong nativeHandle) {
73 | VulkanTutorialApplication *app = reinterpret_cast(nativeHandle);
74 | app->stop();
75 | }
76 |
77 | }
78 |
--------------------------------------------------------------------------------
/app/src/main/cpp/vulkan_wrapper/vulkan_wrapper.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | // This file is generated.
17 | #ifdef __cplusplus
18 | extern "C" {
19 | #endif
20 |
21 | #include "vulkan_wrapper.h"
22 | #include
23 |
24 | int InitVulkan(void) {
25 | void *libvulkan = dlopen("libvulkan.so", RTLD_NOW | RTLD_LOCAL);
26 | if (!libvulkan) return 0;
27 |
28 | // Vulkan supported, set function addresses
29 | vkCreateInstance = reinterpret_cast(dlsym(libvulkan, "vkCreateInstance"));
30 | vkDestroyInstance = reinterpret_cast(dlsym(libvulkan, "vkDestroyInstance"));
31 | vkEnumeratePhysicalDevices = reinterpret_cast(dlsym(libvulkan, "vkEnumeratePhysicalDevices"));
32 | vkGetPhysicalDeviceFeatures =
33 | reinterpret_cast(dlsym(libvulkan, "vkGetPhysicalDeviceFeatures"));
34 | vkGetPhysicalDeviceFormatProperties =
35 | reinterpret_cast(dlsym(libvulkan, "vkGetPhysicalDeviceFormatProperties"));
36 | vkGetPhysicalDeviceImageFormatProperties = reinterpret_cast(
37 | dlsym(libvulkan, "vkGetPhysicalDeviceImageFormatProperties"));
38 | vkGetPhysicalDeviceProperties =
39 | reinterpret_cast(dlsym(libvulkan, "vkGetPhysicalDeviceProperties"));
40 | vkGetPhysicalDeviceQueueFamilyProperties = reinterpret_cast(
41 | dlsym(libvulkan, "vkGetPhysicalDeviceQueueFamilyProperties"));
42 | vkGetPhysicalDeviceMemoryProperties =
43 | reinterpret_cast(dlsym(libvulkan, "vkGetPhysicalDeviceMemoryProperties"));
44 | vkGetInstanceProcAddr = reinterpret_cast(dlsym(libvulkan, "vkGetInstanceProcAddr"));
45 | vkGetDeviceProcAddr = reinterpret_cast(dlsym(libvulkan, "vkGetDeviceProcAddr"));
46 | vkCreateDevice = reinterpret_cast(dlsym(libvulkan, "vkCreateDevice"));
47 | vkDestroyDevice = reinterpret_cast(dlsym(libvulkan, "vkDestroyDevice"));
48 | vkEnumerateInstanceExtensionProperties =
49 | reinterpret_cast(dlsym(libvulkan, "vkEnumerateInstanceExtensionProperties"));
50 | vkEnumerateDeviceExtensionProperties =
51 | reinterpret_cast(dlsym(libvulkan, "vkEnumerateDeviceExtensionProperties"));
52 | vkEnumerateInstanceLayerProperties =
53 | reinterpret_cast(dlsym(libvulkan, "vkEnumerateInstanceLayerProperties"));
54 | vkEnumerateDeviceLayerProperties =
55 | reinterpret_cast(dlsym(libvulkan, "vkEnumerateDeviceLayerProperties"));
56 | vkGetDeviceQueue = reinterpret_cast(dlsym(libvulkan, "vkGetDeviceQueue"));
57 | vkQueueSubmit = reinterpret_cast(dlsym(libvulkan, "vkQueueSubmit"));
58 | vkQueueWaitIdle = reinterpret_cast(dlsym(libvulkan, "vkQueueWaitIdle"));
59 | vkDeviceWaitIdle = reinterpret_cast(dlsym(libvulkan, "vkDeviceWaitIdle"));
60 | vkAllocateMemory = reinterpret_cast(dlsym(libvulkan, "vkAllocateMemory"));
61 | vkFreeMemory = reinterpret_cast(dlsym(libvulkan, "vkFreeMemory"));
62 | vkMapMemory = reinterpret_cast(dlsym(libvulkan, "vkMapMemory"));
63 | vkUnmapMemory = reinterpret_cast(dlsym(libvulkan, "vkUnmapMemory"));
64 | vkFlushMappedMemoryRanges = reinterpret_cast(dlsym(libvulkan, "vkFlushMappedMemoryRanges"));
65 | vkInvalidateMappedMemoryRanges =
66 | reinterpret_cast(dlsym(libvulkan, "vkInvalidateMappedMemoryRanges"));
67 | vkGetDeviceMemoryCommitment =
68 | reinterpret_cast(dlsym(libvulkan, "vkGetDeviceMemoryCommitment"));
69 | vkBindBufferMemory = reinterpret_cast(dlsym(libvulkan, "vkBindBufferMemory"));
70 | vkBindImageMemory = reinterpret_cast(dlsym(libvulkan, "vkBindImageMemory"));
71 | vkGetBufferMemoryRequirements =
72 | reinterpret_cast(dlsym(libvulkan, "vkGetBufferMemoryRequirements"));
73 | vkGetImageMemoryRequirements =
74 | reinterpret_cast(dlsym(libvulkan, "vkGetImageMemoryRequirements"));
75 | vkGetImageSparseMemoryRequirements =
76 | reinterpret_cast(dlsym(libvulkan, "vkGetImageSparseMemoryRequirements"));
77 | vkGetPhysicalDeviceSparseImageFormatProperties = reinterpret_cast(
78 | dlsym(libvulkan, "vkGetPhysicalDeviceSparseImageFormatProperties"));
79 | vkQueueBindSparse = reinterpret_cast(dlsym(libvulkan, "vkQueueBindSparse"));
80 | vkCreateFence = reinterpret_cast(dlsym(libvulkan, "vkCreateFence"));
81 | vkDestroyFence = reinterpret_cast(dlsym(libvulkan, "vkDestroyFence"));
82 | vkResetFences = reinterpret_cast(dlsym(libvulkan, "vkResetFences"));
83 | vkGetFenceStatus = reinterpret_cast(dlsym(libvulkan, "vkGetFenceStatus"));
84 | vkWaitForFences = reinterpret_cast(dlsym(libvulkan, "vkWaitForFences"));
85 | vkCreateSemaphore = reinterpret_cast(dlsym(libvulkan, "vkCreateSemaphore"));
86 | vkDestroySemaphore = reinterpret_cast(dlsym(libvulkan, "vkDestroySemaphore"));
87 | vkCreateEvent = reinterpret_cast(dlsym(libvulkan, "vkCreateEvent"));
88 | vkDestroyEvent = reinterpret_cast(dlsym(libvulkan, "vkDestroyEvent"));
89 | vkGetEventStatus = reinterpret_cast(dlsym(libvulkan, "vkGetEventStatus"));
90 | vkSetEvent = reinterpret_cast(dlsym(libvulkan, "vkSetEvent"));
91 | vkResetEvent = reinterpret_cast(dlsym(libvulkan, "vkResetEvent"));
92 | vkCreateQueryPool = reinterpret_cast(dlsym(libvulkan, "vkCreateQueryPool"));
93 | vkDestroyQueryPool = reinterpret_cast(dlsym(libvulkan, "vkDestroyQueryPool"));
94 | vkGetQueryPoolResults = reinterpret_cast(dlsym(libvulkan, "vkGetQueryPoolResults"));
95 | vkCreateBuffer = reinterpret_cast(dlsym(libvulkan, "vkCreateBuffer"));
96 | vkDestroyBuffer = reinterpret_cast(dlsym(libvulkan, "vkDestroyBuffer"));
97 | vkCreateBufferView = reinterpret_cast(dlsym(libvulkan, "vkCreateBufferView"));
98 | vkDestroyBufferView = reinterpret_cast(dlsym(libvulkan, "vkDestroyBufferView"));
99 | vkCreateImage = reinterpret_cast(dlsym(libvulkan, "vkCreateImage"));
100 | vkDestroyImage = reinterpret_cast(dlsym(libvulkan, "vkDestroyImage"));
101 | vkGetImageSubresourceLayout =
102 | reinterpret_cast(dlsym(libvulkan, "vkGetImageSubresourceLayout"));
103 | vkCreateImageView = reinterpret_cast(dlsym(libvulkan, "vkCreateImageView"));
104 | vkDestroyImageView = reinterpret_cast(dlsym(libvulkan, "vkDestroyImageView"));
105 | vkCreateShaderModule = reinterpret_cast(dlsym(libvulkan, "vkCreateShaderModule"));
106 | vkDestroyShaderModule = reinterpret_cast(dlsym(libvulkan, "vkDestroyShaderModule"));
107 | vkCreatePipelineCache = reinterpret_cast(dlsym(libvulkan, "vkCreatePipelineCache"));
108 | vkDestroyPipelineCache = reinterpret_cast(dlsym(libvulkan, "vkDestroyPipelineCache"));
109 | vkGetPipelineCacheData = reinterpret_cast(dlsym(libvulkan, "vkGetPipelineCacheData"));
110 | vkMergePipelineCaches = reinterpret_cast(dlsym(libvulkan, "vkMergePipelineCaches"));
111 | vkCreateGraphicsPipelines = reinterpret_cast(dlsym(libvulkan, "vkCreateGraphicsPipelines"));
112 | vkCreateComputePipelines = reinterpret_cast(dlsym(libvulkan, "vkCreateComputePipelines"));
113 | vkDestroyPipeline = reinterpret_cast(dlsym(libvulkan, "vkDestroyPipeline"));
114 | vkCreatePipelineLayout = reinterpret_cast(dlsym(libvulkan, "vkCreatePipelineLayout"));
115 | vkDestroyPipelineLayout = reinterpret_cast(dlsym(libvulkan, "vkDestroyPipelineLayout"));
116 | vkCreateSampler = reinterpret_cast(dlsym(libvulkan, "vkCreateSampler"));
117 | vkDestroySampler = reinterpret_cast(dlsym(libvulkan, "vkDestroySampler"));
118 | vkCreateDescriptorSetLayout =
119 | reinterpret_cast(dlsym(libvulkan, "vkCreateDescriptorSetLayout"));
120 | vkDestroyDescriptorSetLayout =
121 | reinterpret_cast(dlsym(libvulkan, "vkDestroyDescriptorSetLayout"));
122 | vkCreateDescriptorPool = reinterpret_cast(dlsym(libvulkan, "vkCreateDescriptorPool"));
123 | vkDestroyDescriptorPool = reinterpret_cast(dlsym(libvulkan, "vkDestroyDescriptorPool"));
124 | vkResetDescriptorPool = reinterpret_cast(dlsym(libvulkan, "vkResetDescriptorPool"));
125 | vkAllocateDescriptorSets = reinterpret_cast(dlsym(libvulkan, "vkAllocateDescriptorSets"));
126 | vkFreeDescriptorSets = reinterpret_cast(dlsym(libvulkan, "vkFreeDescriptorSets"));
127 | vkUpdateDescriptorSets = reinterpret_cast(dlsym(libvulkan, "vkUpdateDescriptorSets"));
128 | vkCreateFramebuffer = reinterpret_cast(dlsym(libvulkan, "vkCreateFramebuffer"));
129 | vkDestroyFramebuffer = reinterpret_cast(dlsym(libvulkan, "vkDestroyFramebuffer"));
130 | vkCreateRenderPass = reinterpret_cast(dlsym(libvulkan, "vkCreateRenderPass"));
131 | vkDestroyRenderPass = reinterpret_cast(dlsym(libvulkan, "vkDestroyRenderPass"));
132 | vkGetRenderAreaGranularity = reinterpret_cast(dlsym(libvulkan, "vkGetRenderAreaGranularity"));
133 | vkCreateCommandPool = reinterpret_cast(dlsym(libvulkan, "vkCreateCommandPool"));
134 | vkDestroyCommandPool = reinterpret_cast(dlsym(libvulkan, "vkDestroyCommandPool"));
135 | vkResetCommandPool = reinterpret_cast(dlsym(libvulkan, "vkResetCommandPool"));
136 | vkAllocateCommandBuffers = reinterpret_cast(dlsym(libvulkan, "vkAllocateCommandBuffers"));
137 | vkFreeCommandBuffers = reinterpret_cast(dlsym(libvulkan, "vkFreeCommandBuffers"));
138 | vkBeginCommandBuffer = reinterpret_cast(dlsym(libvulkan, "vkBeginCommandBuffer"));
139 | vkEndCommandBuffer = reinterpret_cast(dlsym(libvulkan, "vkEndCommandBuffer"));
140 | vkResetCommandBuffer = reinterpret_cast(dlsym(libvulkan, "vkResetCommandBuffer"));
141 | vkCmdBindPipeline = reinterpret_cast(dlsym(libvulkan, "vkCmdBindPipeline"));
142 | vkCmdSetViewport = reinterpret_cast(dlsym(libvulkan, "vkCmdSetViewport"));
143 | vkCmdSetScissor = reinterpret_cast(dlsym(libvulkan, "vkCmdSetScissor"));
144 | vkCmdSetLineWidth = reinterpret_cast(dlsym(libvulkan, "vkCmdSetLineWidth"));
145 | vkCmdSetDepthBias = reinterpret_cast(dlsym(libvulkan, "vkCmdSetDepthBias"));
146 | vkCmdSetBlendConstants = reinterpret_cast(dlsym(libvulkan, "vkCmdSetBlendConstants"));
147 | vkCmdSetDepthBounds = reinterpret_cast(dlsym(libvulkan, "vkCmdSetDepthBounds"));
148 | vkCmdSetStencilCompareMask = reinterpret_cast(dlsym(libvulkan, "vkCmdSetStencilCompareMask"));
149 | vkCmdSetStencilWriteMask = reinterpret_cast(dlsym(libvulkan, "vkCmdSetStencilWriteMask"));
150 | vkCmdSetStencilReference = reinterpret_cast(dlsym(libvulkan, "vkCmdSetStencilReference"));
151 | vkCmdBindDescriptorSets = reinterpret_cast(dlsym(libvulkan, "vkCmdBindDescriptorSets"));
152 | vkCmdBindIndexBuffer = reinterpret_cast(dlsym(libvulkan, "vkCmdBindIndexBuffer"));
153 | vkCmdBindVertexBuffers = reinterpret_cast(dlsym(libvulkan, "vkCmdBindVertexBuffers"));
154 | vkCmdDraw = reinterpret_cast(dlsym(libvulkan, "vkCmdDraw"));
155 | vkCmdDrawIndexed = reinterpret_cast(dlsym(libvulkan, "vkCmdDrawIndexed"));
156 | vkCmdDrawIndirect = reinterpret_cast(dlsym(libvulkan, "vkCmdDrawIndirect"));
157 | vkCmdDrawIndexedIndirect = reinterpret_cast(dlsym(libvulkan, "vkCmdDrawIndexedIndirect"));
158 | vkCmdDispatch = reinterpret_cast(dlsym(libvulkan, "vkCmdDispatch"));
159 | vkCmdDispatchIndirect = reinterpret_cast(dlsym(libvulkan, "vkCmdDispatchIndirect"));
160 | vkCmdCopyBuffer = reinterpret_cast(dlsym(libvulkan, "vkCmdCopyBuffer"));
161 | vkCmdCopyImage = reinterpret_cast(dlsym(libvulkan, "vkCmdCopyImage"));
162 | vkCmdBlitImage = reinterpret_cast(dlsym(libvulkan, "vkCmdBlitImage"));
163 | vkCmdCopyBufferToImage = reinterpret_cast(dlsym(libvulkan, "vkCmdCopyBufferToImage"));
164 | vkCmdCopyImageToBuffer = reinterpret_cast(dlsym(libvulkan, "vkCmdCopyImageToBuffer"));
165 | vkCmdUpdateBuffer = reinterpret_cast(dlsym(libvulkan, "vkCmdUpdateBuffer"));
166 | vkCmdFillBuffer = reinterpret_cast(dlsym(libvulkan, "vkCmdFillBuffer"));
167 | vkCmdClearColorImage = reinterpret_cast(dlsym(libvulkan, "vkCmdClearColorImage"));
168 | vkCmdClearDepthStencilImage =
169 | reinterpret_cast(dlsym(libvulkan, "vkCmdClearDepthStencilImage"));
170 | vkCmdClearAttachments = reinterpret_cast(dlsym(libvulkan, "vkCmdClearAttachments"));
171 | vkCmdResolveImage = reinterpret_cast(dlsym(libvulkan, "vkCmdResolveImage"));
172 | vkCmdSetEvent = reinterpret_cast(dlsym(libvulkan, "vkCmdSetEvent"));
173 | vkCmdResetEvent = reinterpret_cast(dlsym(libvulkan, "vkCmdResetEvent"));
174 | vkCmdWaitEvents = reinterpret_cast(dlsym(libvulkan, "vkCmdWaitEvents"));
175 | vkCmdPipelineBarrier = reinterpret_cast(dlsym(libvulkan, "vkCmdPipelineBarrier"));
176 | vkCmdBeginQuery = reinterpret_cast(dlsym(libvulkan, "vkCmdBeginQuery"));
177 | vkCmdEndQuery = reinterpret_cast(dlsym(libvulkan, "vkCmdEndQuery"));
178 | vkCmdResetQueryPool = reinterpret_cast(dlsym(libvulkan, "vkCmdResetQueryPool"));
179 | vkCmdWriteTimestamp = reinterpret_cast(dlsym(libvulkan, "vkCmdWriteTimestamp"));
180 | vkCmdCopyQueryPoolResults = reinterpret_cast(dlsym(libvulkan, "vkCmdCopyQueryPoolResults"));
181 | vkCmdPushConstants = reinterpret_cast(dlsym(libvulkan, "vkCmdPushConstants"));
182 | vkCmdBeginRenderPass = reinterpret_cast(dlsym(libvulkan, "vkCmdBeginRenderPass"));
183 | vkCmdNextSubpass = reinterpret_cast(dlsym(libvulkan, "vkCmdNextSubpass"));
184 | vkCmdEndRenderPass = reinterpret_cast(dlsym(libvulkan, "vkCmdEndRenderPass"));
185 | vkCmdExecuteCommands = reinterpret_cast(dlsym(libvulkan, "vkCmdExecuteCommands"));
186 | vkDestroySurfaceKHR = reinterpret_cast(dlsym(libvulkan, "vkDestroySurfaceKHR"));
187 | vkGetPhysicalDeviceSurfaceSupportKHR =
188 | reinterpret_cast(dlsym(libvulkan, "vkGetPhysicalDeviceSurfaceSupportKHR"));
189 | vkGetPhysicalDeviceSurfaceCapabilitiesKHR = reinterpret_cast(
190 | dlsym(libvulkan, "vkGetPhysicalDeviceSurfaceCapabilitiesKHR"));
191 | vkGetPhysicalDeviceSurfaceFormatsKHR =
192 | reinterpret_cast(dlsym(libvulkan, "vkGetPhysicalDeviceSurfaceFormatsKHR"));
193 | vkGetPhysicalDeviceSurfacePresentModesKHR = reinterpret_cast(
194 | dlsym(libvulkan, "vkGetPhysicalDeviceSurfacePresentModesKHR"));
195 | vkCreateSwapchainKHR = reinterpret_cast(dlsym(libvulkan, "vkCreateSwapchainKHR"));
196 | vkDestroySwapchainKHR = reinterpret_cast(dlsym(libvulkan, "vkDestroySwapchainKHR"));
197 | vkGetSwapchainImagesKHR = reinterpret_cast(dlsym(libvulkan, "vkGetSwapchainImagesKHR"));
198 | vkAcquireNextImageKHR = reinterpret_cast(dlsym(libvulkan, "vkAcquireNextImageKHR"));
199 | vkQueuePresentKHR = reinterpret_cast(dlsym(libvulkan, "vkQueuePresentKHR"));
200 | vkGetPhysicalDeviceDisplayPropertiesKHR =
201 | reinterpret_cast(dlsym(libvulkan, "vkGetPhysicalDeviceDisplayPropertiesKHR"));
202 | vkGetPhysicalDeviceDisplayPlanePropertiesKHR = reinterpret_cast(
203 | dlsym(libvulkan, "vkGetPhysicalDeviceDisplayPlanePropertiesKHR"));
204 | vkGetDisplayPlaneSupportedDisplaysKHR =
205 | reinterpret_cast(dlsym(libvulkan, "vkGetDisplayPlaneSupportedDisplaysKHR"));
206 | vkGetDisplayModePropertiesKHR =
207 | reinterpret_cast(dlsym(libvulkan, "vkGetDisplayModePropertiesKHR"));
208 | vkCreateDisplayModeKHR = reinterpret_cast(dlsym(libvulkan, "vkCreateDisplayModeKHR"));
209 | vkGetDisplayPlaneCapabilitiesKHR =
210 | reinterpret_cast(dlsym(libvulkan, "vkGetDisplayPlaneCapabilitiesKHR"));
211 | vkCreateDisplayPlaneSurfaceKHR =
212 | reinterpret_cast(dlsym(libvulkan, "vkCreateDisplayPlaneSurfaceKHR"));
213 | vkCreateSharedSwapchainsKHR =
214 | reinterpret_cast(dlsym(libvulkan, "vkCreateSharedSwapchainsKHR"));
215 |
216 | #ifdef VK_USE_PLATFORM_XLIB_KHR
217 | vkCreateXlibSurfaceKHR = reinterpret_cast(dlsym(libvulkan, "vkCreateXlibSurfaceKHR"));
218 | vkGetPhysicalDeviceXlibPresentationSupportKHR = reinterpret_cast(
219 | dlsym(libvulkan, "vkGetPhysicalDeviceXlibPresentationSupportKHR"));
220 | #endif
221 |
222 | #ifdef VK_USE_PLATFORM_XCB_KHR
223 | vkCreateXcbSurfaceKHR = reinterpret_cast(dlsym(libvulkan, "vkCreateXcbSurfaceKHR"));
224 | vkGetPhysicalDeviceXcbPresentationSupportKHR = reinterpret_cast(
225 | dlsym(libvulkan, "vkGetPhysicalDeviceXcbPresentationSupportKHR"));
226 | #endif
227 |
228 | #ifdef VK_USE_PLATFORM_WAYLAND_KHR
229 | vkCreateWaylandSurfaceKHR = reinterpret_cast(dlsym(libvulkan, "vkCreateWaylandSurfaceKHR"));
230 | vkGetPhysicalDeviceWaylandPresentationSupportKHR = reinterpret_cast(
231 | dlsym(libvulkan, "vkGetPhysicalDeviceWaylandPresentationSupportKHR"));
232 | #endif
233 |
234 | #ifdef VK_USE_PLATFORM_MIR_KHR
235 | vkCreateMirSurfaceKHR = reinterpret_cast(dlsym(libvulkan, "vkCreateMirSurfaceKHR"));
236 | vkGetPhysicalDeviceMirPresentationSupportKHR = reinterpret_cast(
237 | dlsym(libvulkan, "vkGetPhysicalDeviceMirPresentationSupportKHR"));
238 | #endif
239 |
240 | #ifdef VK_USE_PLATFORM_ANDROID_KHR
241 | vkCreateAndroidSurfaceKHR = reinterpret_cast(dlsym(libvulkan, "vkCreateAndroidSurfaceKHR"));
242 | #endif
243 |
244 | #ifdef VK_USE_PLATFORM_WIN32_KHR
245 | vkCreateWin32SurfaceKHR = reinterpret_cast(dlsym(libvulkan, "vkCreateWin32SurfaceKHR"));
246 | vkGetPhysicalDeviceWin32PresentationSupportKHR = reinterpret_cast(
247 | dlsym(libvulkan, "vkGetPhysicalDeviceWin32PresentationSupportKHR"));
248 | #endif
249 | return 1;
250 | }
251 |
252 | // No Vulkan support, do not set function addresses
253 | PFN_vkCreateInstance vkCreateInstance;
254 | PFN_vkDestroyInstance vkDestroyInstance;
255 | PFN_vkEnumeratePhysicalDevices vkEnumeratePhysicalDevices;
256 | PFN_vkGetPhysicalDeviceFeatures vkGetPhysicalDeviceFeatures;
257 | PFN_vkGetPhysicalDeviceFormatProperties vkGetPhysicalDeviceFormatProperties;
258 | PFN_vkGetPhysicalDeviceImageFormatProperties vkGetPhysicalDeviceImageFormatProperties;
259 | PFN_vkGetPhysicalDeviceProperties vkGetPhysicalDeviceProperties;
260 | PFN_vkGetPhysicalDeviceQueueFamilyProperties vkGetPhysicalDeviceQueueFamilyProperties;
261 | PFN_vkGetPhysicalDeviceMemoryProperties vkGetPhysicalDeviceMemoryProperties;
262 | PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr;
263 | PFN_vkGetDeviceProcAddr vkGetDeviceProcAddr;
264 | PFN_vkCreateDevice vkCreateDevice;
265 | PFN_vkDestroyDevice vkDestroyDevice;
266 | PFN_vkEnumerateInstanceExtensionProperties vkEnumerateInstanceExtensionProperties;
267 | PFN_vkEnumerateDeviceExtensionProperties vkEnumerateDeviceExtensionProperties;
268 | PFN_vkEnumerateInstanceLayerProperties vkEnumerateInstanceLayerProperties;
269 | PFN_vkEnumerateDeviceLayerProperties vkEnumerateDeviceLayerProperties;
270 | PFN_vkGetDeviceQueue vkGetDeviceQueue;
271 | PFN_vkQueueSubmit vkQueueSubmit;
272 | PFN_vkQueueWaitIdle vkQueueWaitIdle;
273 | PFN_vkDeviceWaitIdle vkDeviceWaitIdle;
274 | PFN_vkAllocateMemory vkAllocateMemory;
275 | PFN_vkFreeMemory vkFreeMemory;
276 | PFN_vkMapMemory vkMapMemory;
277 | PFN_vkUnmapMemory vkUnmapMemory;
278 | PFN_vkFlushMappedMemoryRanges vkFlushMappedMemoryRanges;
279 | PFN_vkInvalidateMappedMemoryRanges vkInvalidateMappedMemoryRanges;
280 | PFN_vkGetDeviceMemoryCommitment vkGetDeviceMemoryCommitment;
281 | PFN_vkBindBufferMemory vkBindBufferMemory;
282 | PFN_vkBindImageMemory vkBindImageMemory;
283 | PFN_vkGetBufferMemoryRequirements vkGetBufferMemoryRequirements;
284 | PFN_vkGetImageMemoryRequirements vkGetImageMemoryRequirements;
285 | PFN_vkGetImageSparseMemoryRequirements vkGetImageSparseMemoryRequirements;
286 | PFN_vkGetPhysicalDeviceSparseImageFormatProperties vkGetPhysicalDeviceSparseImageFormatProperties;
287 | PFN_vkQueueBindSparse vkQueueBindSparse;
288 | PFN_vkCreateFence vkCreateFence;
289 | PFN_vkDestroyFence vkDestroyFence;
290 | PFN_vkResetFences vkResetFences;
291 | PFN_vkGetFenceStatus vkGetFenceStatus;
292 | PFN_vkWaitForFences vkWaitForFences;
293 | PFN_vkCreateSemaphore vkCreateSemaphore;
294 | PFN_vkDestroySemaphore vkDestroySemaphore;
295 | PFN_vkCreateEvent vkCreateEvent;
296 | PFN_vkDestroyEvent vkDestroyEvent;
297 | PFN_vkGetEventStatus vkGetEventStatus;
298 | PFN_vkSetEvent vkSetEvent;
299 | PFN_vkResetEvent vkResetEvent;
300 | PFN_vkCreateQueryPool vkCreateQueryPool;
301 | PFN_vkDestroyQueryPool vkDestroyQueryPool;
302 | PFN_vkGetQueryPoolResults vkGetQueryPoolResults;
303 | PFN_vkCreateBuffer vkCreateBuffer;
304 | PFN_vkDestroyBuffer vkDestroyBuffer;
305 | PFN_vkCreateBufferView vkCreateBufferView;
306 | PFN_vkDestroyBufferView vkDestroyBufferView;
307 | PFN_vkCreateImage vkCreateImage;
308 | PFN_vkDestroyImage vkDestroyImage;
309 | PFN_vkGetImageSubresourceLayout vkGetImageSubresourceLayout;
310 | PFN_vkCreateImageView vkCreateImageView;
311 | PFN_vkDestroyImageView vkDestroyImageView;
312 | PFN_vkCreateShaderModule vkCreateShaderModule;
313 | PFN_vkDestroyShaderModule vkDestroyShaderModule;
314 | PFN_vkCreatePipelineCache vkCreatePipelineCache;
315 | PFN_vkDestroyPipelineCache vkDestroyPipelineCache;
316 | PFN_vkGetPipelineCacheData vkGetPipelineCacheData;
317 | PFN_vkMergePipelineCaches vkMergePipelineCaches;
318 | PFN_vkCreateGraphicsPipelines vkCreateGraphicsPipelines;
319 | PFN_vkCreateComputePipelines vkCreateComputePipelines;
320 | PFN_vkDestroyPipeline vkDestroyPipeline;
321 | PFN_vkCreatePipelineLayout vkCreatePipelineLayout;
322 | PFN_vkDestroyPipelineLayout vkDestroyPipelineLayout;
323 | PFN_vkCreateSampler vkCreateSampler;
324 | PFN_vkDestroySampler vkDestroySampler;
325 | PFN_vkCreateDescriptorSetLayout vkCreateDescriptorSetLayout;
326 | PFN_vkDestroyDescriptorSetLayout vkDestroyDescriptorSetLayout;
327 | PFN_vkCreateDescriptorPool vkCreateDescriptorPool;
328 | PFN_vkDestroyDescriptorPool vkDestroyDescriptorPool;
329 | PFN_vkResetDescriptorPool vkResetDescriptorPool;
330 | PFN_vkAllocateDescriptorSets vkAllocateDescriptorSets;
331 | PFN_vkFreeDescriptorSets vkFreeDescriptorSets;
332 | PFN_vkUpdateDescriptorSets vkUpdateDescriptorSets;
333 | PFN_vkCreateFramebuffer vkCreateFramebuffer;
334 | PFN_vkDestroyFramebuffer vkDestroyFramebuffer;
335 | PFN_vkCreateRenderPass vkCreateRenderPass;
336 | PFN_vkDestroyRenderPass vkDestroyRenderPass;
337 | PFN_vkGetRenderAreaGranularity vkGetRenderAreaGranularity;
338 | PFN_vkCreateCommandPool vkCreateCommandPool;
339 | PFN_vkDestroyCommandPool vkDestroyCommandPool;
340 | PFN_vkResetCommandPool vkResetCommandPool;
341 | PFN_vkAllocateCommandBuffers vkAllocateCommandBuffers;
342 | PFN_vkFreeCommandBuffers vkFreeCommandBuffers;
343 | PFN_vkBeginCommandBuffer vkBeginCommandBuffer;
344 | PFN_vkEndCommandBuffer vkEndCommandBuffer;
345 | PFN_vkResetCommandBuffer vkResetCommandBuffer;
346 | PFN_vkCmdBindPipeline vkCmdBindPipeline;
347 | PFN_vkCmdSetViewport vkCmdSetViewport;
348 | PFN_vkCmdSetScissor vkCmdSetScissor;
349 | PFN_vkCmdSetLineWidth vkCmdSetLineWidth;
350 | PFN_vkCmdSetDepthBias vkCmdSetDepthBias;
351 | PFN_vkCmdSetBlendConstants vkCmdSetBlendConstants;
352 | PFN_vkCmdSetDepthBounds vkCmdSetDepthBounds;
353 | PFN_vkCmdSetStencilCompareMask vkCmdSetStencilCompareMask;
354 | PFN_vkCmdSetStencilWriteMask vkCmdSetStencilWriteMask;
355 | PFN_vkCmdSetStencilReference vkCmdSetStencilReference;
356 | PFN_vkCmdBindDescriptorSets vkCmdBindDescriptorSets;
357 | PFN_vkCmdBindIndexBuffer vkCmdBindIndexBuffer;
358 | PFN_vkCmdBindVertexBuffers vkCmdBindVertexBuffers;
359 | PFN_vkCmdDraw vkCmdDraw;
360 | PFN_vkCmdDrawIndexed vkCmdDrawIndexed;
361 | PFN_vkCmdDrawIndirect vkCmdDrawIndirect;
362 | PFN_vkCmdDrawIndexedIndirect vkCmdDrawIndexedIndirect;
363 | PFN_vkCmdDispatch vkCmdDispatch;
364 | PFN_vkCmdDispatchIndirect vkCmdDispatchIndirect;
365 | PFN_vkCmdCopyBuffer vkCmdCopyBuffer;
366 | PFN_vkCmdCopyImage vkCmdCopyImage;
367 | PFN_vkCmdBlitImage vkCmdBlitImage;
368 | PFN_vkCmdCopyBufferToImage vkCmdCopyBufferToImage;
369 | PFN_vkCmdCopyImageToBuffer vkCmdCopyImageToBuffer;
370 | PFN_vkCmdUpdateBuffer vkCmdUpdateBuffer;
371 | PFN_vkCmdFillBuffer vkCmdFillBuffer;
372 | PFN_vkCmdClearColorImage vkCmdClearColorImage;
373 | PFN_vkCmdClearDepthStencilImage vkCmdClearDepthStencilImage;
374 | PFN_vkCmdClearAttachments vkCmdClearAttachments;
375 | PFN_vkCmdResolveImage vkCmdResolveImage;
376 | PFN_vkCmdSetEvent vkCmdSetEvent;
377 | PFN_vkCmdResetEvent vkCmdResetEvent;
378 | PFN_vkCmdWaitEvents vkCmdWaitEvents;
379 | PFN_vkCmdPipelineBarrier vkCmdPipelineBarrier;
380 | PFN_vkCmdBeginQuery vkCmdBeginQuery;
381 | PFN_vkCmdEndQuery vkCmdEndQuery;
382 | PFN_vkCmdResetQueryPool vkCmdResetQueryPool;
383 | PFN_vkCmdWriteTimestamp vkCmdWriteTimestamp;
384 | PFN_vkCmdCopyQueryPoolResults vkCmdCopyQueryPoolResults;
385 | PFN_vkCmdPushConstants vkCmdPushConstants;
386 | PFN_vkCmdBeginRenderPass vkCmdBeginRenderPass;
387 | PFN_vkCmdNextSubpass vkCmdNextSubpass;
388 | PFN_vkCmdEndRenderPass vkCmdEndRenderPass;
389 | PFN_vkCmdExecuteCommands vkCmdExecuteCommands;
390 | PFN_vkDestroySurfaceKHR vkDestroySurfaceKHR;
391 | PFN_vkGetPhysicalDeviceSurfaceSupportKHR vkGetPhysicalDeviceSurfaceSupportKHR;
392 | PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR vkGetPhysicalDeviceSurfaceCapabilitiesKHR;
393 | PFN_vkGetPhysicalDeviceSurfaceFormatsKHR vkGetPhysicalDeviceSurfaceFormatsKHR;
394 | PFN_vkGetPhysicalDeviceSurfacePresentModesKHR vkGetPhysicalDeviceSurfacePresentModesKHR;
395 | PFN_vkCreateSwapchainKHR vkCreateSwapchainKHR;
396 | PFN_vkDestroySwapchainKHR vkDestroySwapchainKHR;
397 | PFN_vkGetSwapchainImagesKHR vkGetSwapchainImagesKHR;
398 | PFN_vkAcquireNextImageKHR vkAcquireNextImageKHR;
399 | PFN_vkQueuePresentKHR vkQueuePresentKHR;
400 | PFN_vkGetPhysicalDeviceDisplayPropertiesKHR vkGetPhysicalDeviceDisplayPropertiesKHR;
401 | PFN_vkGetPhysicalDeviceDisplayPlanePropertiesKHR vkGetPhysicalDeviceDisplayPlanePropertiesKHR;
402 | PFN_vkGetDisplayPlaneSupportedDisplaysKHR vkGetDisplayPlaneSupportedDisplaysKHR;
403 | PFN_vkGetDisplayModePropertiesKHR vkGetDisplayModePropertiesKHR;
404 | PFN_vkCreateDisplayModeKHR vkCreateDisplayModeKHR;
405 | PFN_vkGetDisplayPlaneCapabilitiesKHR vkGetDisplayPlaneCapabilitiesKHR;
406 | PFN_vkCreateDisplayPlaneSurfaceKHR vkCreateDisplayPlaneSurfaceKHR;
407 | PFN_vkCreateSharedSwapchainsKHR vkCreateSharedSwapchainsKHR;
408 |
409 | #ifdef VK_USE_PLATFORM_XLIB_KHR
410 | PFN_vkCreateXlibSurfaceKHR vkCreateXlibSurfaceKHR;
411 | PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR vkGetPhysicalDeviceXlibPresentationSupportKHR;
412 | #endif
413 |
414 | #ifdef VK_USE_PLATFORM_XCB_KHR
415 | PFN_vkCreateXcbSurfaceKHR vkCreateXcbSurfaceKHR;
416 | PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR vkGetPhysicalDeviceXcbPresentationSupportKHR;
417 | #endif
418 |
419 | #ifdef VK_USE_PLATFORM_WAYLAND_KHR
420 | PFN_vkCreateWaylandSurfaceKHR vkCreateWaylandSurfaceKHR;
421 | PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR vkGetPhysicalDeviceWaylandPresentationSupportKHR;
422 | #endif
423 |
424 | #ifdef VK_USE_PLATFORM_MIR_KHR
425 | PFN_vkCreateMirSurfaceKHR vkCreateMirSurfaceKHR;
426 | PFN_vkGetPhysicalDeviceMirPresentationSupportKHR vkGetPhysicalDeviceMirPresentationSupportKHR;
427 | #endif
428 |
429 | #ifdef VK_USE_PLATFORM_ANDROID_KHR
430 | PFN_vkCreateAndroidSurfaceKHR vkCreateAndroidSurfaceKHR;
431 | #endif
432 |
433 | #ifdef VK_USE_PLATFORM_WIN32_KHR
434 | PFN_vkCreateWin32SurfaceKHR vkCreateWin32SurfaceKHR;
435 | PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR vkGetPhysicalDeviceWin32PresentationSupportKHR;
436 | #endif
437 | PFN_vkCreateDebugReportCallbackEXT vkCreateDebugReportCallbackEXT;
438 | PFN_vkDestroyDebugReportCallbackEXT vkDestroyDebugReportCallbackEXT;
439 | PFN_vkDebugReportMessageEXT vkDebugReportMessageEXT;
440 |
441 | #ifdef __cplusplus
442 | }
443 | #endif
444 |
--------------------------------------------------------------------------------
/app/src/main/cpp/vulkan_wrapper/vulkan_wrapper.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | // This file is generated.
17 | #ifndef VULKAN_WRAPPER_H
18 | #define VULKAN_WRAPPER_H
19 |
20 | #ifdef __cplusplus
21 | extern "C" {
22 | #endif
23 |
24 | #define VK_NO_PROTOTYPES 1
25 | #include
26 |
27 | /* Initialize the Vulkan function pointer variables declared in this header.
28 | * Returns 0 if vulkan is not available, non-zero if it is available.
29 | */
30 | int InitVulkan(void);
31 |
32 | // VK_core
33 | extern PFN_vkCreateInstance vkCreateInstance;
34 | extern PFN_vkDestroyInstance vkDestroyInstance;
35 | extern PFN_vkEnumeratePhysicalDevices vkEnumeratePhysicalDevices;
36 | extern PFN_vkGetPhysicalDeviceFeatures vkGetPhysicalDeviceFeatures;
37 | extern PFN_vkGetPhysicalDeviceFormatProperties vkGetPhysicalDeviceFormatProperties;
38 | extern PFN_vkGetPhysicalDeviceImageFormatProperties vkGetPhysicalDeviceImageFormatProperties;
39 | extern PFN_vkGetPhysicalDeviceProperties vkGetPhysicalDeviceProperties;
40 | extern PFN_vkGetPhysicalDeviceQueueFamilyProperties vkGetPhysicalDeviceQueueFamilyProperties;
41 | extern PFN_vkGetPhysicalDeviceMemoryProperties vkGetPhysicalDeviceMemoryProperties;
42 | extern PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr;
43 | extern PFN_vkGetDeviceProcAddr vkGetDeviceProcAddr;
44 | extern PFN_vkCreateDevice vkCreateDevice;
45 | extern PFN_vkDestroyDevice vkDestroyDevice;
46 | extern PFN_vkEnumerateInstanceExtensionProperties vkEnumerateInstanceExtensionProperties;
47 | extern PFN_vkEnumerateDeviceExtensionProperties vkEnumerateDeviceExtensionProperties;
48 | extern PFN_vkEnumerateInstanceLayerProperties vkEnumerateInstanceLayerProperties;
49 | extern PFN_vkEnumerateDeviceLayerProperties vkEnumerateDeviceLayerProperties;
50 | extern PFN_vkGetDeviceQueue vkGetDeviceQueue;
51 | extern PFN_vkQueueSubmit vkQueueSubmit;
52 | extern PFN_vkQueueWaitIdle vkQueueWaitIdle;
53 | extern PFN_vkDeviceWaitIdle vkDeviceWaitIdle;
54 | extern PFN_vkAllocateMemory vkAllocateMemory;
55 | extern PFN_vkFreeMemory vkFreeMemory;
56 | extern PFN_vkMapMemory vkMapMemory;
57 | extern PFN_vkUnmapMemory vkUnmapMemory;
58 | extern PFN_vkFlushMappedMemoryRanges vkFlushMappedMemoryRanges;
59 | extern PFN_vkInvalidateMappedMemoryRanges vkInvalidateMappedMemoryRanges;
60 | extern PFN_vkGetDeviceMemoryCommitment vkGetDeviceMemoryCommitment;
61 | extern PFN_vkBindBufferMemory vkBindBufferMemory;
62 | extern PFN_vkBindImageMemory vkBindImageMemory;
63 | extern PFN_vkGetBufferMemoryRequirements vkGetBufferMemoryRequirements;
64 | extern PFN_vkGetImageMemoryRequirements vkGetImageMemoryRequirements;
65 | extern PFN_vkGetImageSparseMemoryRequirements vkGetImageSparseMemoryRequirements;
66 | extern PFN_vkGetPhysicalDeviceSparseImageFormatProperties vkGetPhysicalDeviceSparseImageFormatProperties;
67 | extern PFN_vkQueueBindSparse vkQueueBindSparse;
68 | extern PFN_vkCreateFence vkCreateFence;
69 | extern PFN_vkDestroyFence vkDestroyFence;
70 | extern PFN_vkResetFences vkResetFences;
71 | extern PFN_vkGetFenceStatus vkGetFenceStatus;
72 | extern PFN_vkWaitForFences vkWaitForFences;
73 | extern PFN_vkCreateSemaphore vkCreateSemaphore;
74 | extern PFN_vkDestroySemaphore vkDestroySemaphore;
75 | extern PFN_vkCreateEvent vkCreateEvent;
76 | extern PFN_vkDestroyEvent vkDestroyEvent;
77 | extern PFN_vkGetEventStatus vkGetEventStatus;
78 | extern PFN_vkSetEvent vkSetEvent;
79 | extern PFN_vkResetEvent vkResetEvent;
80 | extern PFN_vkCreateQueryPool vkCreateQueryPool;
81 | extern PFN_vkDestroyQueryPool vkDestroyQueryPool;
82 | extern PFN_vkGetQueryPoolResults vkGetQueryPoolResults;
83 | extern PFN_vkCreateBuffer vkCreateBuffer;
84 | extern PFN_vkDestroyBuffer vkDestroyBuffer;
85 | extern PFN_vkCreateBufferView vkCreateBufferView;
86 | extern PFN_vkDestroyBufferView vkDestroyBufferView;
87 | extern PFN_vkCreateImage vkCreateImage;
88 | extern PFN_vkDestroyImage vkDestroyImage;
89 | extern PFN_vkGetImageSubresourceLayout vkGetImageSubresourceLayout;
90 | extern PFN_vkCreateImageView vkCreateImageView;
91 | extern PFN_vkDestroyImageView vkDestroyImageView;
92 | extern PFN_vkCreateShaderModule vkCreateShaderModule;
93 | extern PFN_vkDestroyShaderModule vkDestroyShaderModule;
94 | extern PFN_vkCreatePipelineCache vkCreatePipelineCache;
95 | extern PFN_vkDestroyPipelineCache vkDestroyPipelineCache;
96 | extern PFN_vkGetPipelineCacheData vkGetPipelineCacheData;
97 | extern PFN_vkMergePipelineCaches vkMergePipelineCaches;
98 | extern PFN_vkCreateGraphicsPipelines vkCreateGraphicsPipelines;
99 | extern PFN_vkCreateComputePipelines vkCreateComputePipelines;
100 | extern PFN_vkDestroyPipeline vkDestroyPipeline;
101 | extern PFN_vkCreatePipelineLayout vkCreatePipelineLayout;
102 | extern PFN_vkDestroyPipelineLayout vkDestroyPipelineLayout;
103 | extern PFN_vkCreateSampler vkCreateSampler;
104 | extern PFN_vkDestroySampler vkDestroySampler;
105 | extern PFN_vkCreateDescriptorSetLayout vkCreateDescriptorSetLayout;
106 | extern PFN_vkDestroyDescriptorSetLayout vkDestroyDescriptorSetLayout;
107 | extern PFN_vkCreateDescriptorPool vkCreateDescriptorPool;
108 | extern PFN_vkDestroyDescriptorPool vkDestroyDescriptorPool;
109 | extern PFN_vkResetDescriptorPool vkResetDescriptorPool;
110 | extern PFN_vkAllocateDescriptorSets vkAllocateDescriptorSets;
111 | extern PFN_vkFreeDescriptorSets vkFreeDescriptorSets;
112 | extern PFN_vkUpdateDescriptorSets vkUpdateDescriptorSets;
113 | extern PFN_vkCreateFramebuffer vkCreateFramebuffer;
114 | extern PFN_vkDestroyFramebuffer vkDestroyFramebuffer;
115 | extern PFN_vkCreateRenderPass vkCreateRenderPass;
116 | extern PFN_vkDestroyRenderPass vkDestroyRenderPass;
117 | extern PFN_vkGetRenderAreaGranularity vkGetRenderAreaGranularity;
118 | extern PFN_vkCreateCommandPool vkCreateCommandPool;
119 | extern PFN_vkDestroyCommandPool vkDestroyCommandPool;
120 | extern PFN_vkResetCommandPool vkResetCommandPool;
121 | extern PFN_vkAllocateCommandBuffers vkAllocateCommandBuffers;
122 | extern PFN_vkFreeCommandBuffers vkFreeCommandBuffers;
123 | extern PFN_vkBeginCommandBuffer vkBeginCommandBuffer;
124 | extern PFN_vkEndCommandBuffer vkEndCommandBuffer;
125 | extern PFN_vkResetCommandBuffer vkResetCommandBuffer;
126 | extern PFN_vkCmdBindPipeline vkCmdBindPipeline;
127 | extern PFN_vkCmdSetViewport vkCmdSetViewport;
128 | extern PFN_vkCmdSetScissor vkCmdSetScissor;
129 | extern PFN_vkCmdSetLineWidth vkCmdSetLineWidth;
130 | extern PFN_vkCmdSetDepthBias vkCmdSetDepthBias;
131 | extern PFN_vkCmdSetBlendConstants vkCmdSetBlendConstants;
132 | extern PFN_vkCmdSetDepthBounds vkCmdSetDepthBounds;
133 | extern PFN_vkCmdSetStencilCompareMask vkCmdSetStencilCompareMask;
134 | extern PFN_vkCmdSetStencilWriteMask vkCmdSetStencilWriteMask;
135 | extern PFN_vkCmdSetStencilReference vkCmdSetStencilReference;
136 | extern PFN_vkCmdBindDescriptorSets vkCmdBindDescriptorSets;
137 | extern PFN_vkCmdBindIndexBuffer vkCmdBindIndexBuffer;
138 | extern PFN_vkCmdBindVertexBuffers vkCmdBindVertexBuffers;
139 | extern PFN_vkCmdDraw vkCmdDraw;
140 | extern PFN_vkCmdDrawIndexed vkCmdDrawIndexed;
141 | extern PFN_vkCmdDrawIndirect vkCmdDrawIndirect;
142 | extern PFN_vkCmdDrawIndexedIndirect vkCmdDrawIndexedIndirect;
143 | extern PFN_vkCmdDispatch vkCmdDispatch;
144 | extern PFN_vkCmdDispatchIndirect vkCmdDispatchIndirect;
145 | extern PFN_vkCmdCopyBuffer vkCmdCopyBuffer;
146 | extern PFN_vkCmdCopyImage vkCmdCopyImage;
147 | extern PFN_vkCmdBlitImage vkCmdBlitImage;
148 | extern PFN_vkCmdCopyBufferToImage vkCmdCopyBufferToImage;
149 | extern PFN_vkCmdCopyImageToBuffer vkCmdCopyImageToBuffer;
150 | extern PFN_vkCmdUpdateBuffer vkCmdUpdateBuffer;
151 | extern PFN_vkCmdFillBuffer vkCmdFillBuffer;
152 | extern PFN_vkCmdClearColorImage vkCmdClearColorImage;
153 | extern PFN_vkCmdClearDepthStencilImage vkCmdClearDepthStencilImage;
154 | extern PFN_vkCmdClearAttachments vkCmdClearAttachments;
155 | extern PFN_vkCmdResolveImage vkCmdResolveImage;
156 | extern PFN_vkCmdSetEvent vkCmdSetEvent;
157 | extern PFN_vkCmdResetEvent vkCmdResetEvent;
158 | extern PFN_vkCmdWaitEvents vkCmdWaitEvents;
159 | extern PFN_vkCmdPipelineBarrier vkCmdPipelineBarrier;
160 | extern PFN_vkCmdBeginQuery vkCmdBeginQuery;
161 | extern PFN_vkCmdEndQuery vkCmdEndQuery;
162 | extern PFN_vkCmdResetQueryPool vkCmdResetQueryPool;
163 | extern PFN_vkCmdWriteTimestamp vkCmdWriteTimestamp;
164 | extern PFN_vkCmdCopyQueryPoolResults vkCmdCopyQueryPoolResults;
165 | extern PFN_vkCmdPushConstants vkCmdPushConstants;
166 | extern PFN_vkCmdBeginRenderPass vkCmdBeginRenderPass;
167 | extern PFN_vkCmdNextSubpass vkCmdNextSubpass;
168 | extern PFN_vkCmdEndRenderPass vkCmdEndRenderPass;
169 | extern PFN_vkCmdExecuteCommands vkCmdExecuteCommands;
170 |
171 | // VK_KHR_surface
172 | extern PFN_vkDestroySurfaceKHR vkDestroySurfaceKHR;
173 | extern PFN_vkGetPhysicalDeviceSurfaceSupportKHR vkGetPhysicalDeviceSurfaceSupportKHR;
174 | extern PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR vkGetPhysicalDeviceSurfaceCapabilitiesKHR;
175 | extern PFN_vkGetPhysicalDeviceSurfaceFormatsKHR vkGetPhysicalDeviceSurfaceFormatsKHR;
176 | extern PFN_vkGetPhysicalDeviceSurfacePresentModesKHR vkGetPhysicalDeviceSurfacePresentModesKHR;
177 |
178 | // VK_KHR_swapchain
179 | extern PFN_vkCreateSwapchainKHR vkCreateSwapchainKHR;
180 | extern PFN_vkDestroySwapchainKHR vkDestroySwapchainKHR;
181 | extern PFN_vkGetSwapchainImagesKHR vkGetSwapchainImagesKHR;
182 | extern PFN_vkAcquireNextImageKHR vkAcquireNextImageKHR;
183 | extern PFN_vkQueuePresentKHR vkQueuePresentKHR;
184 |
185 | // VK_KHR_display
186 | extern PFN_vkGetPhysicalDeviceDisplayPropertiesKHR vkGetPhysicalDeviceDisplayPropertiesKHR;
187 | extern PFN_vkGetPhysicalDeviceDisplayPlanePropertiesKHR vkGetPhysicalDeviceDisplayPlanePropertiesKHR;
188 | extern PFN_vkGetDisplayPlaneSupportedDisplaysKHR vkGetDisplayPlaneSupportedDisplaysKHR;
189 | extern PFN_vkGetDisplayModePropertiesKHR vkGetDisplayModePropertiesKHR;
190 | extern PFN_vkCreateDisplayModeKHR vkCreateDisplayModeKHR;
191 | extern PFN_vkGetDisplayPlaneCapabilitiesKHR vkGetDisplayPlaneCapabilitiesKHR;
192 | extern PFN_vkCreateDisplayPlaneSurfaceKHR vkCreateDisplayPlaneSurfaceKHR;
193 |
194 | // VK_KHR_display_swapchain
195 | extern PFN_vkCreateSharedSwapchainsKHR vkCreateSharedSwapchainsKHR;
196 |
197 | #ifdef VK_USE_PLATFORM_XLIB_KHR
198 | // VK_KHR_xlib_surface
199 | extern PFN_vkCreateXlibSurfaceKHR vkCreateXlibSurfaceKHR;
200 | extern PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR vkGetPhysicalDeviceXlibPresentationSupportKHR;
201 | #endif
202 |
203 | #ifdef VK_USE_PLATFORM_XCB_KHR
204 | // VK_KHR_xcb_surface
205 | extern PFN_vkCreateXcbSurfaceKHR vkCreateXcbSurfaceKHR;
206 | extern PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR vkGetPhysicalDeviceXcbPresentationSupportKHR;
207 | #endif
208 |
209 | #ifdef VK_USE_PLATFORM_WAYLAND_KHR
210 | // VK_KHR_wayland_surface
211 | extern PFN_vkCreateWaylandSurfaceKHR vkCreateWaylandSurfaceKHR;
212 | extern PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR vkGetPhysicalDeviceWaylandPresentationSupportKHR;
213 | #endif
214 |
215 | #ifdef VK_USE_PLATFORM_MIR_KHR
216 | // VK_KHR_mir_surface
217 | extern PFN_vkCreateMirSurfaceKHR vkCreateMirSurfaceKHR;
218 | extern PFN_vkGetPhysicalDeviceMirPresentationSupportKHR vkGetPhysicalDeviceMirPresentationSupportKHR;
219 | #endif
220 |
221 | #ifdef VK_USE_PLATFORM_ANDROID_KHR
222 | // VK_KHR_android_surface
223 | extern PFN_vkCreateAndroidSurfaceKHR vkCreateAndroidSurfaceKHR;
224 | #endif
225 |
226 | #ifdef VK_USE_PLATFORM_WIN32_KHR
227 | // VK_KHR_win32_surface
228 | extern PFN_vkCreateWin32SurfaceKHR vkCreateWin32SurfaceKHR;
229 | extern PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR vkGetPhysicalDeviceWin32PresentationSupportKHR;
230 | #endif
231 |
232 | // VK_KHR_sampler_mirror_clamp_to_edge
233 |
234 | #ifdef __cplusplus
235 | }
236 | #endif
237 |
238 | #endif // VULKAN_WRAPPER_H
239 |
--------------------------------------------------------------------------------
/app/src/main/java/com/github/piasy/vulkantutorial/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.github.piasy.vulkantutorial;
2 |
3 | import android.content.res.AssetManager;
4 | import android.os.Bundle;
5 | import android.support.v7.app.AppCompatActivity;
6 | import android.view.SurfaceHolder;
7 | import android.view.SurfaceView;
8 | import android.view.View;
9 | import android.view.ViewGroup;
10 |
11 | public class MainActivity extends AppCompatActivity implements SurfaceHolder.Callback {
12 |
13 | private static final String VERTEX_SHADER = "shaders/triangle.vert.spv";
14 | private static final String FRAGMENT_SHADER = "shaders/triangle.frag.spv";
15 |
16 | private VulkanTutorialApplication mTriangleApplication;
17 | private AssetManager mAssetManager;
18 | private boolean mFirstSurfaceChange;
19 | private boolean mFullscreen = true;
20 |
21 | @Override
22 | protected void onCreate(Bundle savedInstanceState) {
23 | super.onCreate(savedInstanceState);
24 | setContentView(R.layout.activity_main);
25 |
26 | mAssetManager = getAssets();
27 |
28 | mTriangleApplication = new VulkanTutorialApplication(mAssetManager, VERTEX_SHADER,
29 | FRAGMENT_SHADER);
30 |
31 | final SurfaceView surfaceView = (SurfaceView) findViewById(R.id.surface);
32 | surfaceView.getHolder().addCallback(this);
33 |
34 | findViewById(R.id.mBtnResize).setOnClickListener(new View.OnClickListener() {
35 | @Override
36 | public void onClick(final View v) {
37 | mFullscreen = !mFullscreen;
38 |
39 | ViewGroup.LayoutParams params = surfaceView.getLayoutParams();
40 |
41 | if (mFullscreen) {
42 | params.width = ViewGroup.LayoutParams.MATCH_PARENT;
43 | params.height = ViewGroup.LayoutParams.MATCH_PARENT;
44 | } else {
45 | params.width = 180;
46 | params.height = 320;
47 | }
48 |
49 | surfaceView.setLayoutParams(params);
50 | }
51 | });
52 | }
53 |
54 | @Override
55 | protected void onResume() {
56 | super.onResume();
57 |
58 | mTriangleApplication.resume();
59 | }
60 |
61 | @Override
62 | protected void onPause() {
63 | super.onPause();
64 |
65 | mTriangleApplication.pause();
66 | }
67 |
68 | @Override
69 | protected void onDestroy() {
70 | super.onDestroy();
71 |
72 | mTriangleApplication.stop();
73 | }
74 |
75 | @Override
76 | public void surfaceCreated(final SurfaceHolder holder) {
77 | mTriangleApplication.run(holder.getSurface());
78 | mFirstSurfaceChange = true;
79 | }
80 |
81 | @Override
82 | public void surfaceChanged(final SurfaceHolder holder, final int format, final int width,
83 | final int height) {
84 | if (!mFirstSurfaceChange) {
85 | mTriangleApplication.surfaceChanged();
86 | }
87 | mFirstSurfaceChange = false;
88 | }
89 |
90 | @Override
91 | public void surfaceDestroyed(final SurfaceHolder holder) {
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/app/src/main/java/com/github/piasy/vulkantutorial/VulkanTutorialApplication.java:
--------------------------------------------------------------------------------
1 | package com.github.piasy.vulkantutorial;
2 |
3 | import android.content.res.AssetManager;
4 | import android.view.Surface;
5 |
6 | /**
7 | * Created by Piasy{github.com/Piasy} on 30/06/2017.
8 | */
9 |
10 | public class VulkanTutorialApplication {
11 |
12 | static {
13 | System.loadLibrary("vulkan");
14 | System.loadLibrary("vulkan-tutorial");
15 | }
16 |
17 | private long mNativeHandle;
18 |
19 | public VulkanTutorialApplication(AssetManager assetManager, String vertexShader,
20 | String fragmentShader) {
21 | mNativeHandle = create(assetManager, vertexShader, fragmentShader);
22 | }
23 |
24 | private static native long create(AssetManager assetManager, String vertexShader,
25 | String fragmentShader);
26 |
27 | private static native void run(long nativeHandle, Surface surface);
28 |
29 | private static native void pause(long nativeHandle);
30 |
31 | private static native void resume(long nativeHandle);
32 |
33 | private static native void surfaceChanged(long nativeHandle);
34 |
35 | private static native void stop(long nativeHandle);
36 |
37 | public void run(final Surface surface) {
38 | new Thread(new Runnable() {
39 | @Override
40 | public void run() {
41 | VulkanTutorialApplication.run(mNativeHandle, surface);
42 | }
43 | }).start();
44 | }
45 |
46 | public void pause() {
47 | pause(mNativeHandle);
48 | }
49 |
50 | public void resume() {
51 | resume(mNativeHandle);
52 | }
53 |
54 | public void surfaceChanged() {
55 | surfaceChanged(mNativeHandle);
56 | }
57 |
58 | public void stop() {
59 | stop(mNativeHandle);
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
15 |
16 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Piasy/VulkanTutorial-Android/7c295c1acb052acfa901a61b896b617aa273e817/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Piasy/VulkanTutorial-Android/7c295c1acb052acfa901a61b896b617aa273e817/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Piasy/VulkanTutorial-Android/7c295c1acb052acfa901a61b896b617aa273e817/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Piasy/VulkanTutorial-Android/7c295c1acb052acfa901a61b896b617aa273e817/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Piasy/VulkanTutorial-Android/7c295c1acb052acfa901a61b896b617aa273e817/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Piasy/VulkanTutorial-Android/7c295c1acb052acfa901a61b896b617aa273e817/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Piasy/VulkanTutorial-Android/7c295c1acb052acfa901a61b896b617aa273e817/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Piasy/VulkanTutorial-Android/7c295c1acb052acfa901a61b896b617aa273e817/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Piasy/VulkanTutorial-Android/7c295c1acb052acfa901a61b896b617aa273e817/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Piasy/VulkanTutorial-Android/7c295c1acb052acfa901a61b896b617aa273e817/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | VulkanTutorial
3 |
4 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/main/shaders/triangle.frag:
--------------------------------------------------------------------------------
1 | #version 450
2 | #extension GL_ARB_separate_shader_objects : enable
3 |
4 | layout(binding = 1) uniform sampler2D texSampler;
5 |
6 | layout(location = 0) in vec3 fragColor;
7 | layout(location = 1) in vec2 fragTexCoord;
8 |
9 | layout(location = 0) out vec4 outColor;
10 |
11 | void main() {
12 | outColor = texture(texSampler, fragTexCoord);
13 | }
--------------------------------------------------------------------------------
/app/src/main/shaders/triangle.vert:
--------------------------------------------------------------------------------
1 | #version 450
2 | #extension GL_ARB_separate_shader_objects : enable
3 |
4 | layout(binding = 0) uniform UniformBufferObject {
5 | mat4 model;
6 | mat4 view;
7 | mat4 proj;
8 | } ubo;
9 |
10 | layout(location = 0) in vec2 inPosition;
11 | layout(location = 1) in vec3 inColor;
12 | layout(location = 2) in vec2 inTexCoord;
13 |
14 | layout(location = 0) out vec3 fragColor;
15 | layout(location = 1) out vec2 fragTexCoord;
16 |
17 | out gl_PerVertex {
18 | vec4 gl_Position;
19 | };
20 |
21 | void main() {
22 | gl_Position = ubo.proj * ubo.view * ubo.model * vec4(inPosition, 0.0, 1.0);
23 | fragColor = inColor;
24 | fragTexCoord = inTexCoord;
25 | }
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | repositories {
5 | jcenter()
6 | google()
7 | }
8 | dependencies {
9 | classpath 'com.android.tools.build:gradle:3.1.2'
10 |
11 | // NOTE: Do not place your application dependencies here; they belong
12 | // in the individual module build.gradle files
13 | }
14 | }
15 |
16 | allprojects {
17 | repositories {
18 | jcenter()
19 | google()
20 | }
21 | }
22 |
23 | task clean(type: Delete) {
24 | delete rootProject.buildDir
25 | }
26 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | org.gradle.jvmargs=-Xmx1536m
13 |
14 | # When configured, Gradle will run in incubating parallel mode.
15 | # This option should only be used with decoupled projects. More details, visit
16 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
17 | # org.gradle.parallel=true
18 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Piasy/VulkanTutorial-Android/7c295c1acb052acfa901a61b896b617aa273e817/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Mon Jun 26 21:20:35 CST 2017
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.7-all.zip
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # Attempt to set APP_HOME
46 | # Resolve links: $0 may be a link
47 | PRG="$0"
48 | # Need this for relative symlinks.
49 | while [ -h "$PRG" ] ; do
50 | ls=`ls -ld "$PRG"`
51 | link=`expr "$ls" : '.*-> \(.*\)$'`
52 | if expr "$link" : '/.*' > /dev/null; then
53 | PRG="$link"
54 | else
55 | PRG=`dirname "$PRG"`"/$link"
56 | fi
57 | done
58 | SAVED="`pwd`"
59 | cd "`dirname \"$PRG\"`/" >/dev/null
60 | APP_HOME="`pwd -P`"
61 | cd "$SAVED" >/dev/null
62 |
63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
64 |
65 | # Determine the Java command to use to start the JVM.
66 | if [ -n "$JAVA_HOME" ] ; then
67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
68 | # IBM's JDK on AIX uses strange locations for the executables
69 | JAVACMD="$JAVA_HOME/jre/sh/java"
70 | else
71 | JAVACMD="$JAVA_HOME/bin/java"
72 | fi
73 | if [ ! -x "$JAVACMD" ] ; then
74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
75 |
76 | Please set the JAVA_HOME variable in your environment to match the
77 | location of your Java installation."
78 | fi
79 | else
80 | JAVACMD="java"
81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
82 |
83 | Please set the JAVA_HOME variable in your environment to match the
84 | location of your Java installation."
85 | fi
86 |
87 | # Increase the maximum file descriptors if we can.
88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
89 | MAX_FD_LIMIT=`ulimit -H -n`
90 | if [ $? -eq 0 ] ; then
91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
92 | MAX_FD="$MAX_FD_LIMIT"
93 | fi
94 | ulimit -n $MAX_FD
95 | if [ $? -ne 0 ] ; then
96 | warn "Could not set maximum file descriptor limit: $MAX_FD"
97 | fi
98 | else
99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
100 | fi
101 | fi
102 |
103 | # For Darwin, add options to specify how the application appears in the dock
104 | if $darwin; then
105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
106 | fi
107 |
108 | # For Cygwin, switch paths to Windows format before running java
109 | if $cygwin ; then
110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
112 | JAVACMD=`cygpath --unix "$JAVACMD"`
113 |
114 | # We build the pattern for arguments to be converted via cygpath
115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
116 | SEP=""
117 | for dir in $ROOTDIRSRAW ; do
118 | ROOTDIRS="$ROOTDIRS$SEP$dir"
119 | SEP="|"
120 | done
121 | OURCYGPATTERN="(^($ROOTDIRS))"
122 | # Add a user-defined pattern to the cygpath arguments
123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
125 | fi
126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
127 | i=0
128 | for arg in "$@" ; do
129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
131 |
132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
134 | else
135 | eval `echo args$i`="\"$arg\""
136 | fi
137 | i=$((i+1))
138 | done
139 | case $i in
140 | (0) set -- ;;
141 | (1) set -- "$args0" ;;
142 | (2) set -- "$args0" "$args1" ;;
143 | (3) set -- "$args0" "$args1" "$args2" ;;
144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
150 | esac
151 | fi
152 |
153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
154 | function splitJvmOpts() {
155 | JVM_OPTS=("$@")
156 | }
157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
159 |
160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
161 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
--------------------------------------------------------------------------------