diff --git a/android/base/vulkanandroidbase.hpp b/android/base/vulkanandroidbase.hpp deleted file mode 100644 index 596fadd6..00000000 --- a/android/base/vulkanandroidbase.hpp +++ /dev/null @@ -1,881 +0,0 @@ -/* -* Shared android example base -* -* Will be replaced once the main examples get proper android support -* -* Copyright (C) 2016 by Sascha Willems - www.saschawillems.de -* -* This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) -*/ - -#pragma once - -#include -#include -#include -#include -#include -#include -#include - -#include -#include "vulkanandroid.h" -#include "vulkanswapchain.hpp" -#include "vulkantools.h" - -class VulkanAndroidExampleBase -{ -private: - std::chrono::high_resolution_clock::time_point tStart; - VkShaderModule loadShaderModule(const char *fileName, VkShaderStageFlagBits stage) - { - // Load shader from compressed asset - AAsset* asset = AAssetManager_open(app->activity->assetManager, fileName, AASSET_MODE_STREAMING); - assert(asset); - size_t size = AAsset_getLength(asset); - assert(size > 0); - - char *shaderCode = new char[size]; - AAsset_read(asset, shaderCode, size); - AAsset_close(asset); - - VkShaderModule shaderModule; - VkShaderModuleCreateInfo moduleCreateInfo; - VkResult err; - - moduleCreateInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; - moduleCreateInfo.pNext = NULL; - - moduleCreateInfo.codeSize = size; - moduleCreateInfo.pCode = (uint32_t*)shaderCode; - moduleCreateInfo.flags = 0; - err = vkCreateShaderModule(device, &moduleCreateInfo, NULL, &shaderModule); - assert(!err); - - return shaderModule; - } -public: - bool prepared = false; - - struct android_app* app; - uint32_t width; - uint32_t height; - float frameTimer = 1.0f; - - struct Texture { - VkSampler sampler; - VkImage image; - VkImageLayout imageLayout; - VkDeviceMemory deviceMemory; - VkImageView view; - uint32_t width, height; - uint32_t mipLevels; - }; - - VkPhysicalDeviceMemoryProperties deviceMemoryProperties; - VkInstance instance; - VkPhysicalDevice physicalDevice; - VkDevice device; - VkQueue queue; - VkCommandPool cmdPool; - VkCommandBuffer setupCmdBuffer = VK_NULL_HANDLE; - VkCommandBuffer postPresentCmdBuffer = VK_NULL_HANDLE; - VkCommandBuffer prePresentCmdBuffer = VK_NULL_HANDLE; - std::vector drawCmdBuffers; - VkPipelineCache pipelineCache; - VkDescriptorPool descriptorPool; - VulkanSwapChain swapChain; - std::vector shaderModules; - - uint32_t currentBuffer = 0; - struct - { - VkImage image; - VkDeviceMemory mem; - VkImageView view; - } depthStencil; - std::vectorframeBuffers; - VkRenderPass renderPass; - - struct { - VkSemaphore presentComplete; - VkSemaphore submitSignal; - } semaphores; - - VkBool32 getMemoryType(uint32_t typeBits, VkFlags properties, uint32_t * typeIndex) - { - for (uint32_t i = 0; i < 32; i++) - { - if ((typeBits & 1) == 1) - { - if ((deviceMemoryProperties.memoryTypes[i].propertyFlags & properties) == properties) - { - *typeIndex = i; - return true; - } - } - typeBits >>= 1; - } - return false; - } - - void initVulkan() - { - bool libLoaded = loadVulkanLibrary(); - assert(libLoaded); - - VkResult vkRes; - - // Instance - VkApplicationInfo appInfo = {}; - appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; - appInfo.pApplicationName = "Vulkan Android Example"; - appInfo.applicationVersion = 1; - appInfo.pEngineName = "VulkanAndroidExample"; - appInfo.engineVersion = 1; - // todo : Workaround to support implementations that are not using the latest SDK - appInfo.apiVersion = VK_MAKE_VERSION(1, 0, 1); - - VkInstanceCreateInfo instanceCreateInfo = {}; - instanceCreateInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; - instanceCreateInfo.pApplicationInfo = &appInfo; - - vkRes = vkCreateInstance(&instanceCreateInfo, NULL, &instance); - assert(vkRes == VK_SUCCESS); - - loadVulkanFunctions(instance); - - // Device - // Always use first physical device - uint32_t gpuCount; - vkRes = vkEnumeratePhysicalDevices(instance, &gpuCount, &physicalDevice); - assert(vkRes == VK_SUCCESS); - - // Find a queue that supports graphics operations - uint32_t graphicsQueueIndex = 0; - uint32_t queueCount; - vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueCount, NULL); - assert(queueCount >= 1); - - std::vector queueProps; - queueProps.resize(queueCount); - vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueCount, queueProps.data()); - - for (graphicsQueueIndex = 0; graphicsQueueIndex < queueCount; graphicsQueueIndex++) - { - if (queueProps[graphicsQueueIndex].queueFlags & VK_QUEUE_GRAPHICS_BIT) - break; - } - assert(graphicsQueueIndex < queueCount); - - // Request the queue - float queuePriorities = 0.0f; - VkDeviceQueueCreateInfo queueCreateInfo = {}; - queueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; - queueCreateInfo.queueFamilyIndex = graphicsQueueIndex; - queueCreateInfo.queueCount = 1; - queueCreateInfo.pQueuePriorities = &queuePriorities; - - // Create device - VkDeviceCreateInfo deviceCreateInfo = {}; - deviceCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; - deviceCreateInfo.queueCreateInfoCount = 1; - deviceCreateInfo.pQueueCreateInfos = &queueCreateInfo; - - vkRes = vkCreateDevice(physicalDevice, &deviceCreateInfo, nullptr, &device); - assert(vkRes == VK_SUCCESS); - - // Get graphics queue - vkGetDeviceQueue(device, graphicsQueueIndex, 0, &queue); - - // Device memory properties (for finding appropriate memory types) - vkGetPhysicalDeviceMemoryProperties(physicalDevice, &deviceMemoryProperties); - - // Swap chain - swapChain.connect(instance, physicalDevice, device); - swapChain.initSurface(app->window); - - // Command buffer pool - VkCommandPoolCreateInfo cmdPoolInfo = {}; - cmdPoolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; - cmdPoolInfo.queueFamilyIndex = swapChain.queueNodeIndex; - cmdPoolInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; - vkRes = vkCreateCommandPool(device, &cmdPoolInfo, nullptr, &cmdPool); - assert(!vkRes); - - // Pipeline cache - VkPipelineCacheCreateInfo pipelineCacheCreateInfo = {}; - pipelineCacheCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO; - VkResult err = vkCreatePipelineCache(device, &pipelineCacheCreateInfo, nullptr, &pipelineCache); - assert(!err); - - // Create semaphores for synchronization - VkSemaphoreCreateInfo semaphoreCreateInfo = vkTools::initializers::semaphoreCreateInfo(); - - err = vkCreateSemaphore(device, &semaphoreCreateInfo, nullptr, &semaphores.presentComplete); - assert(!err); - err = vkCreateSemaphore(device, &semaphoreCreateInfo, nullptr, &semaphores.submitSignal); - assert(!err); - - createSetupCommandBuffer(); - startSetupCommandBuffer(); - - swapChain.create(setupCmdBuffer, &width, &height); - - setupDepthStencil(); - setupRenderPass(); - setupFrameBuffer(); - - flushSetupCommandBuffer(); - - createCommandBuffers(); - } - - void cleanUpVulkan() - { - swapChain.cleanup(); - - vkDestroyDescriptorPool(device, descriptorPool, nullptr); - if (setupCmdBuffer != VK_NULL_HANDLE) - { - vkFreeCommandBuffers(device, cmdPool, 1, &setupCmdBuffer); - - } - vkFreeCommandBuffers(device, cmdPool, drawCmdBuffers.size(), drawCmdBuffers.data()); - vkFreeCommandBuffers(device, cmdPool, 1, &prePresentCmdBuffer); - vkFreeCommandBuffers(device, cmdPool, 1, &postPresentCmdBuffer); - - vkDestroyRenderPass(device, renderPass, nullptr); - for (uint32_t i = 0; i < frameBuffers.size(); i++) - { - vkDestroyFramebuffer(device, frameBuffers[i], nullptr); - } - - for (auto& shaderModule : shaderModules) - { - vkDestroyShaderModule(device, shaderModule, nullptr); - } - - vkDestroyImageView(device, depthStencil.view, nullptr); - vkDestroyImage(device, depthStencil.image, nullptr); - vkFreeMemory(device, depthStencil.mem, nullptr); - - vkDestroySemaphore(device, semaphores.presentComplete, nullptr); - vkDestroySemaphore(device, semaphores.submitSignal, nullptr); - - vkDestroyPipelineCache(device, pipelineCache, nullptr); - vkDestroyDevice(device, nullptr); - vkDestroyInstance(instance, nullptr); - - freeVulkanLibrary(); - } - - VkPipelineShaderStageCreateInfo loadShader(const char * fileName, VkShaderStageFlagBits stage) - { - VkPipelineShaderStageCreateInfo shaderStage = {}; - shaderStage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; - shaderStage.stage = stage; - shaderStage.module = loadShaderModule(fileName, stage); - shaderStage.pName = "main"; - assert(shaderStage.module != NULL); - shaderModules.push_back(shaderStage.module); - return shaderStage; - } - - void createSetupCommandBuffer() - { - VkCommandBufferAllocateInfo cmdBufAllocateInfo = - vkTools::initializers::commandBufferAllocateInfo( - cmdPool, - VK_COMMAND_BUFFER_LEVEL_PRIMARY, - 1); - - VkResult vkRes = vkAllocateCommandBuffers(device, &cmdBufAllocateInfo, &setupCmdBuffer); - assert(!vkRes); - } - - void startSetupCommandBuffer() - { - VkCommandBufferBeginInfo cmdBufInfo = vkTools::initializers::commandBufferBeginInfo(); - vkBeginCommandBuffer(setupCmdBuffer, &cmdBufInfo); - } - - void flushSetupCommandBuffer() - { - VkResult err; - - if (setupCmdBuffer == VK_NULL_HANDLE) - return; - - err = vkEndCommandBuffer(setupCmdBuffer); - assert(!err); - - VkSubmitInfo submitInfo = {}; - submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; - submitInfo.commandBufferCount = 1; - submitInfo.pCommandBuffers = &setupCmdBuffer; - - err = vkQueueSubmit(queue, 1, &submitInfo, VK_NULL_HANDLE); - assert(!err); - - err = vkQueueWaitIdle(queue); - assert(!err); - } - - void setupDepthStencil() - { - VkImageCreateInfo image = {}; - image.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; - image.pNext = NULL; - image.imageType = VK_IMAGE_TYPE_2D; - image.format = VK_FORMAT_D24_UNORM_S8_UINT; - image.extent = { width, height, 1 }; - image.mipLevels = 1; - image.arrayLayers = 1; - image.samples = VK_SAMPLE_COUNT_1_BIT; - image.tiling = VK_IMAGE_TILING_OPTIMAL; - image.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT; - image.flags = 0; - - VkMemoryAllocateInfo mem_alloc = {}; - mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; - mem_alloc.pNext = NULL; - mem_alloc.allocationSize = 0; - mem_alloc.memoryTypeIndex = 0; - - VkImageViewCreateInfo depthStencilView = {}; - depthStencilView.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; - depthStencilView.pNext = NULL; - depthStencilView.viewType = VK_IMAGE_VIEW_TYPE_2D; - depthStencilView.format = VK_FORMAT_D24_UNORM_S8_UINT; - depthStencilView.flags = 0; - depthStencilView.subresourceRange = {}; - depthStencilView.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT; - depthStencilView.subresourceRange.baseMipLevel = 0; - depthStencilView.subresourceRange.levelCount = 1; - depthStencilView.subresourceRange.baseArrayLayer = 0; - depthStencilView.subresourceRange.layerCount = 1; - - VkMemoryRequirements memReqs; - VkResult err; - - err = vkCreateImage(device, &image, nullptr, &depthStencil.image); - assert(!err); - vkGetImageMemoryRequirements(device, depthStencil.image, &memReqs); - mem_alloc.allocationSize = memReqs.size; - getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &mem_alloc.memoryTypeIndex); - err = vkAllocateMemory(device, &mem_alloc, nullptr, &depthStencil.mem); - assert(!err); - - err = vkBindImageMemory(device, depthStencil.image, depthStencil.mem, 0); - assert(!err); - vkTools::setImageLayout(setupCmdBuffer, depthStencil.image, VK_IMAGE_ASPECT_DEPTH_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); - - depthStencilView.image = depthStencil.image; - err = vkCreateImageView(device, &depthStencilView, nullptr, &depthStencil.view); - assert(!err); - } - - void setupFrameBuffer() - { - VkImageView attachments[2]; - - // Depth/Stencil attachment is the same for all frame buffers - attachments[1] = depthStencil.view; - - VkFramebufferCreateInfo frameBufferCreateInfo = {}; - frameBufferCreateInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; - frameBufferCreateInfo.pNext = NULL; - frameBufferCreateInfo.renderPass = renderPass; - frameBufferCreateInfo.attachmentCount = 2; - frameBufferCreateInfo.pAttachments = attachments; - frameBufferCreateInfo.width = width; - frameBufferCreateInfo.height = height; - frameBufferCreateInfo.layers = 1; - - // Create frame buffers for every swap chain image - frameBuffers.resize(swapChain.imageCount); - for (uint32_t i = 0; i < frameBuffers.size(); i++) - { - attachments[0] = swapChain.buffers[i].view; - VkResult err = vkCreateFramebuffer(device, &frameBufferCreateInfo, nullptr, &frameBuffers[i]); - assert(!err); - } - } - - void setupRenderPass() - { - VkAttachmentDescription attachments[2]; - attachments[0].format = VK_FORMAT_R8G8B8A8_UNORM; - attachments[0].samples = VK_SAMPLE_COUNT_1_BIT; - attachments[0].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; - attachments[0].storeOp = VK_ATTACHMENT_STORE_OP_STORE; - attachments[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - attachments[0].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; - attachments[0].initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - attachments[0].finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - - attachments[1].format = VK_FORMAT_D24_UNORM_S8_UINT; - attachments[1].samples = VK_SAMPLE_COUNT_1_BIT; - attachments[1].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; - attachments[1].storeOp = VK_ATTACHMENT_STORE_OP_STORE; - attachments[1].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - attachments[1].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; - attachments[1].initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; - attachments[1].finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; - - VkAttachmentReference colorReference = {}; - colorReference.attachment = 0; - colorReference.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - - VkAttachmentReference depthReference = {}; - depthReference.attachment = 1; - depthReference.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; - - VkSubpassDescription subpass = {}; - subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; - subpass.flags = 0; - subpass.inputAttachmentCount = 0; - subpass.pInputAttachments = NULL; - subpass.colorAttachmentCount = 1; - subpass.pColorAttachments = &colorReference; - subpass.pResolveAttachments = NULL; - subpass.pDepthStencilAttachment = &depthReference; - subpass.preserveAttachmentCount = 0; - subpass.pPreserveAttachments = NULL; - - VkRenderPassCreateInfo renderPassInfo = {}; - renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; - renderPassInfo.pNext = NULL; - renderPassInfo.attachmentCount = 2; - renderPassInfo.pAttachments = attachments; - renderPassInfo.subpassCount = 1; - renderPassInfo.pSubpasses = &subpass; - renderPassInfo.dependencyCount = 0; - renderPassInfo.pDependencies = NULL; - - VkResult err; - - err = vkCreateRenderPass(device, &renderPassInfo, nullptr, &renderPass); - assert(!err); - } - - void createCommandBuffers() - { - drawCmdBuffers.resize(swapChain.imageCount); - - VkCommandBufferAllocateInfo cmdBufAllocateInfo = - vkTools::initializers::commandBufferAllocateInfo( - cmdPool, - VK_COMMAND_BUFFER_LEVEL_PRIMARY, - drawCmdBuffers.size()); - - VkResult vkRes = vkAllocateCommandBuffers(device, &cmdBufAllocateInfo, drawCmdBuffers.data()); - assert(!vkRes); - - cmdBufAllocateInfo.commandBufferCount = 1; - // Pre present - vkRes = vkAllocateCommandBuffers(device, &cmdBufAllocateInfo, &prePresentCmdBuffer); - assert(!vkRes); - // Post present - vkRes = vkAllocateCommandBuffers(device, &cmdBufAllocateInfo, &postPresentCmdBuffer); - assert(!vkRes); - } - - void submitPrePresentBarrier(VkImage image) - { - VkCommandBufferBeginInfo cmdBufInfo = vkTools::initializers::commandBufferBeginInfo(); - - VkResult vkRes = vkBeginCommandBuffer(prePresentCmdBuffer, &cmdBufInfo); - assert(!vkRes); - - VkImageMemoryBarrier prePresentBarrier = vkTools::initializers::imageMemoryBarrier(); - prePresentBarrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; - prePresentBarrier.dstAccessMask = 0; - prePresentBarrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - prePresentBarrier.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; - prePresentBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; - prePresentBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; - prePresentBarrier.subresourceRange = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }; - prePresentBarrier.image = image; - - vkCmdPipelineBarrier( - prePresentCmdBuffer, - VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, - VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, - VK_FLAGS_NONE, - 0, nullptr, // No memory barriers, - 0, nullptr, // No buffer barriers, - 1, &prePresentBarrier); - - vkRes = vkEndCommandBuffer(prePresentCmdBuffer); - assert(!vkRes); - - VkSubmitInfo submitInfo = vkTools::initializers::submitInfo(); - submitInfo.commandBufferCount = 1; - submitInfo.pCommandBuffers = &prePresentCmdBuffer; - - vkRes = vkQueueSubmit(queue, 1, &submitInfo, VK_NULL_HANDLE); - assert(!vkRes); - } - - void submitPostPresentBarrier(VkImage image) - { - VkCommandBufferBeginInfo cmdBufInfo = vkTools::initializers::commandBufferBeginInfo(); - - VkResult vkRes = vkBeginCommandBuffer(postPresentCmdBuffer, &cmdBufInfo); - assert(!vkRes); - - VkImageMemoryBarrier postPresentBarrier = vkTools::initializers::imageMemoryBarrier(); - postPresentBarrier.srcAccessMask = 0; - postPresentBarrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; - postPresentBarrier.oldLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; - postPresentBarrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - postPresentBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; - postPresentBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; - postPresentBarrier.subresourceRange = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }; - postPresentBarrier.image = image; - - vkCmdPipelineBarrier( - postPresentCmdBuffer, - VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, - VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, - 0, - 0, nullptr, // No memory barriers, - 0, nullptr, // No buffer barriers, - 1, &postPresentBarrier); - - vkRes = vkEndCommandBuffer(postPresentCmdBuffer); - assert(!vkRes); - - VkSubmitInfo submitInfo = vkTools::initializers::submitInfo(); - submitInfo.commandBufferCount = 1; - submitInfo.pCommandBuffers = &postPresentCmdBuffer; - - vkRes = vkQueueSubmit(queue, 1, &submitInfo, VK_NULL_HANDLE); - assert(!vkRes); - } - - void loadTexture(const char* fileName, VkFormat format, Texture *texture, bool forceLinearTiling) - { - VkFormatProperties formatProperties; - VkResult err; - - AAsset* asset = AAssetManager_open(app->activity->assetManager, fileName, AASSET_MODE_STREAMING); - assert(asset); - size_t size = AAsset_getLength(asset); - assert(size > 0); - - void *textureData = malloc(size); - AAsset_read(asset, textureData, size); - AAsset_close(asset); - - gli::texture2D tex2D(gli::load((const char*)textureData, size)); - assert(!tex2D.empty()); - - texture->width = tex2D[0].dimensions().x; - texture->height = tex2D[0].dimensions().y; - texture->mipLevels = tex2D.levels(); - - // Get device properites for the requested texture format - vkGetPhysicalDeviceFormatProperties(physicalDevice, format, &formatProperties); - - // Only use linear tiling if requested (and supported by the device) - // Support for linear tiling is mostly limited, so prefer to use - // optimal tiling instead - // On most implementations linear tiling will only support a very - // limited amount of formats and features (mip maps, cubemaps, arrays, etc.) - VkBool32 useStaging = true; - - // Only use linear tiling if forced - if (forceLinearTiling) - { - // Don't use linear if format is not supported for (linear) shader sampling - useStaging = !(formatProperties.linearTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT); - } - - VkImageCreateInfo imageCreateInfo = vkTools::initializers::imageCreateInfo(); - imageCreateInfo.imageType = VK_IMAGE_TYPE_2D; - imageCreateInfo.format = format; - imageCreateInfo.mipLevels = 1; - imageCreateInfo.arrayLayers = 1; - imageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT; - imageCreateInfo.tiling = VK_IMAGE_TILING_LINEAR; - imageCreateInfo.usage = (useStaging) ? VK_IMAGE_USAGE_TRANSFER_SRC_BIT : VK_IMAGE_USAGE_SAMPLED_BIT; - imageCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; - imageCreateInfo.flags = 0; - imageCreateInfo.extent = { texture->width, texture->height, 1 }; - - VkMemoryAllocateInfo memAllocInfo = vkTools::initializers::memoryAllocateInfo(); - VkMemoryRequirements memReqs; - - startSetupCommandBuffer(); - - if (useStaging) - { - // Load all available mip levels into linear textures - // and copy to optimal tiling target - struct MipLevel { - VkImage image; - VkDeviceMemory memory; - }; - std::vector mipLevels; - mipLevels.resize(texture->mipLevels); - - // Copy mip levels - for (uint32_t level = 0; level < texture->mipLevels; ++level) - { - imageCreateInfo.extent.width = tex2D[level].dimensions().x; - imageCreateInfo.extent.height = tex2D[level].dimensions().y; - imageCreateInfo.extent.depth = 1; - - err = vkCreateImage(device, &imageCreateInfo, nullptr, &mipLevels[level].image); - assert(!err); - - vkGetImageMemoryRequirements(device, mipLevels[level].image, &memReqs); - memAllocInfo.allocationSize = memReqs.size; - getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, &memAllocInfo.memoryTypeIndex); - err = vkAllocateMemory(device, &memAllocInfo, nullptr, &mipLevels[level].memory); - assert(!err); - err = vkBindImageMemory(device, mipLevels[level].image, mipLevels[level].memory, 0); - assert(!err); - - VkImageSubresource subRes = {}; - subRes.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - - VkSubresourceLayout subResLayout; - void *data; - - vkGetImageSubresourceLayout(device, mipLevels[level].image, &subRes, &subResLayout); - assert(!err); - err = vkMapMemory(device, mipLevels[level].memory, 0, memReqs.size, 0, &data); - assert(!err); - size_t levelSize = tex2D[level].size(); - memcpy(data, tex2D[level].data(), levelSize); - vkUnmapMemory(device, mipLevels[level].memory); - - // Image barrier for linear image (base) - // Linear image will be used as a source for the copy - vkTools::setImageLayout( - setupCmdBuffer, - mipLevels[level].image, - VK_IMAGE_ASPECT_COLOR_BIT, - VK_IMAGE_LAYOUT_UNDEFINED, - VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); - } - - // Setup texture as blit target with optimal tiling - imageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL; - imageCreateInfo.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; - imageCreateInfo.mipLevels = texture->mipLevels; - imageCreateInfo.extent = { texture->width, texture->height, 1 }; - - err = vkCreateImage(device, &imageCreateInfo, nullptr, &texture->image); - assert(!err); - - vkGetImageMemoryRequirements(device, texture->image, &memReqs); - - memAllocInfo.allocationSize = memReqs.size; - - getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &memAllocInfo.memoryTypeIndex); - err = vkAllocateMemory(device, &memAllocInfo, nullptr, &texture->deviceMemory); - assert(!err); - err = vkBindImageMemory(device, texture->image, texture->deviceMemory, 0); - assert(!err); - - // Image barrier for optimal image (target) - // Optimal image will be used as destination for the copy - vkTools::setImageLayout( - setupCmdBuffer, - texture->image, - VK_IMAGE_ASPECT_COLOR_BIT, - VK_IMAGE_LAYOUT_UNDEFINED, - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); - - // Copy mip levels one by one - for (uint32_t level = 0; level < texture->mipLevels; ++level) - { - // Copy region for image blit - VkImageCopy copyRegion = {}; - - copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - copyRegion.srcSubresource.baseArrayLayer = 0; - copyRegion.srcSubresource.mipLevel = 0; - copyRegion.srcSubresource.layerCount = 1; - copyRegion.srcOffset = { 0, 0, 0 }; - - copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - copyRegion.dstSubresource.baseArrayLayer = 0; - // Set mip level to copy the linear image to - copyRegion.dstSubresource.mipLevel = level; - copyRegion.dstSubresource.layerCount = 1; - copyRegion.dstOffset = { 0, 0, 0 }; - - copyRegion.extent.width = tex2D[level].dimensions().x; - copyRegion.extent.height = tex2D[level].dimensions().y; - copyRegion.extent.depth = 1; - - // Put image copy into command buffer - vkCmdCopyImage( - setupCmdBuffer, - mipLevels[level].image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, - texture->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - 1, ©Region); - - // Change texture image layout to shader read after the copy - texture->imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; - vkTools::setImageLayout( - setupCmdBuffer, - texture->image, - VK_IMAGE_ASPECT_COLOR_BIT, - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - texture->imageLayout); - } - - flushSetupCommandBuffer(); - - // Clean up linear images - // No longer required after mip levels - // have been transformed over to optimal tiling - for (auto& level : mipLevels) - { - vkDestroyImage(device, level.image, nullptr); - vkFreeMemory(device, level.memory, nullptr); - } - } - else - { - // Prefer using optimal tiling, as linear tiling - // may support only a small set of features - // depending on implementation (e.g. no mip maps, only one layer, etc.) - - VkImage mappableImage; - VkDeviceMemory mappableMemory; - - // Load mip map level 0 to linear tiling image - err = vkCreateImage(device, &imageCreateInfo, nullptr, &mappableImage); - assert(!err); - - // Get memory requirements for this image - // like size and alignment - vkGetImageMemoryRequirements(device, mappableImage, &memReqs); - // Set memory allocation size to required memory size - memAllocInfo.allocationSize = memReqs.size; - - // Get memory type that can be mapped to host memory - getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, &memAllocInfo.memoryTypeIndex); - - // Allocate host memory - err = vkAllocateMemory(device, &memAllocInfo, nullptr, &mappableMemory); - assert(!err); - - // Bind allocated image for use - err = vkBindImageMemory(device, mappableImage, mappableMemory, 0); - assert(!err); - - // Get sub resource layout - // Mip map count, array layer, etc. - VkImageSubresource subRes = {}; - subRes.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - - VkSubresourceLayout subResLayout; - void *data; - - // Get sub resources layout - // Includes row pitch, size offsets, etc. - vkGetImageSubresourceLayout(device, mappableImage, &subRes, &subResLayout); - assert(!err); - - // Map image memory - err = vkMapMemory(device, mappableMemory, 0, memReqs.size, 0, &data); - assert(!err); - - // Copy image data into memory - memcpy(data, tex2D[subRes.mipLevel].data(), tex2D[subRes.mipLevel].size()); - - vkUnmapMemory(device, mappableMemory); - - // Linear tiled images don't need to be staged - // and can be directly used as textures - texture->image = mappableImage; - texture->deviceMemory = mappableMemory; - texture->imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; - - // Setup image memory barrier - vkTools::setImageLayout( - setupCmdBuffer, - texture->image, - VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_UNDEFINED, - texture->imageLayout); - - flushSetupCommandBuffer(); - } - - - // Create sampler - // In Vulkan textures are accessed by samplers - // This separates all the sampling information from the - // texture data - // This means you could have multiple sampler objects - // for the same texture with different settings - // Similar to the samplers available with OpenGL 3.3 - VkSamplerCreateInfo sampler = vkTools::initializers::samplerCreateInfo(); - sampler.magFilter = VK_FILTER_LINEAR; - sampler.minFilter = VK_FILTER_LINEAR; - sampler.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR; - sampler.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; - sampler.addressModeV = sampler.addressModeU; - sampler.addressModeW = sampler.addressModeU; - sampler.mipLodBias = 0.0f; - sampler.compareOp = VK_COMPARE_OP_NEVER; - sampler.minLod = 0.0f; - // Max level-of-detail should match mip level count - sampler.maxLod = (useStaging) ? (float)texture->mipLevels : 0.0f; - // Enable anisotropic filtering - sampler.maxAnisotropy = 8; - sampler.anisotropyEnable = VK_TRUE; - sampler.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE; - err = vkCreateSampler(device, &sampler, nullptr, &texture->sampler); - assert(!err); - - // Create image view - // Textures are not directly accessed by the shaders and - // are abstracted by image views containing additional - // information and sub resource ranges - VkImageViewCreateInfo view = vkTools::initializers::imageViewCreateInfo(); - view.image = VK_NULL_HANDLE; - view.viewType = VK_IMAGE_VIEW_TYPE_2D; - view.format = format; - view.components = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A }; - view.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - view.subresourceRange.baseMipLevel = 0; - view.subresourceRange.baseArrayLayer = 0; - view.subresourceRange.layerCount = 1; - // Linear tiling usually won't support mip maps - // Only set mip map count if optimal tiling is used - view.subresourceRange.levelCount = (useStaging) ? texture->mipLevels : 1; - view.image = texture->image; - err = vkCreateImageView(device, &view, nullptr, &texture->view); - assert(!err); - } - - // Free staging resources used while creating a texture - void destroyTextureImage(Texture *texture) - { - vkDestroyImage(device, texture->image, nullptr); - vkFreeMemory(device, texture->deviceMemory, nullptr); - } - - void startTiming() - { - tStart = std::chrono::high_resolution_clock::now(); - } - - void endTiming() - { - auto tEnd = std::chrono::high_resolution_clock::now(); - auto tDiff = std::chrono::duration(tEnd - tStart).count(); - frameTimer = (float)tDiff; - } - -}; \ No newline at end of file diff --git a/android/build-computeparticles.bat b/android/build-computeparticles.bat new file mode 100644 index 00000000..402e56c7 --- /dev/null +++ b/android/build-computeparticles.bat @@ -0,0 +1 @@ +_build computeparticles %1 \ No newline at end of file diff --git a/android/computeparticles/.gitignore b/android/computeparticles/.gitignore new file mode 100644 index 00000000..7a5d249c --- /dev/null +++ b/android/computeparticles/.gitignore @@ -0,0 +1,10 @@ +/assets/ +/res/ +/bin/ +/libs/ +/obj/ +/build.xml +/local.properties +/project.properties +/proguard-project.txt +*.apk \ No newline at end of file diff --git a/android/computeparticles/AndroidManifest.xml b/android/computeparticles/AndroidManifest.xml new file mode 100644 index 00000000..fbb981fa --- /dev/null +++ b/android/computeparticles/AndroidManifest.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/android/computeparticles/build.bat b/android/computeparticles/build.bat new file mode 100644 index 00000000..88059925 --- /dev/null +++ b/android/computeparticles/build.bat @@ -0,0 +1,20 @@ +cd jni +call ndk-build +if %ERRORLEVEL% EQU 0 ( + echo ndk-build has failed, build cancelled + cd.. + + mkdir "assets\shaders\computeparticles" + xcopy "..\..\data\shaders\computeparticles\*.spv" "assets\shaders\computeparticles" /Y + + mkdir "assets\textures" + xcopy "..\..\data\textures\particle01_rgba.ktx" "assets\textures" /Y + + mkdir "res\drawable" + xcopy "..\..\android\images\icon.png" "res\drawable" /Y + + call ant debug -Dout.final.file=vulkanComputeparticles.apk +) ELSE ( + echo error : ndk-build failed with errors! + cd.. +) diff --git a/android/computeparticles/computeparticles.NativeActivity/android_native_app_glue.c b/android/computeparticles/computeparticles.NativeActivity/android_native_app_glue.c deleted file mode 100644 index 6de5362a..00000000 --- a/android/computeparticles/computeparticles.NativeActivity/android_native_app_glue.c +++ /dev/null @@ -1,426 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "threaded_app", __VA_ARGS__)) -#define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, "threaded_app", __VA_ARGS__)) - -/* For debug builds, always enable the debug traces in this library */ -#ifndef NDEBUG -# define LOGV(...) ((void)__android_log_print(ANDROID_LOG_VERBOSE, "threaded_app", __VA_ARGS__)) -#else -# define LOGV(...) ((void)0) -#endif - -static void free_saved_state(struct android_app* android_app) { - pthread_mutex_lock(&android_app->mutex); - if (android_app->savedState != NULL) { - free(android_app->savedState); - android_app->savedState = NULL; - android_app->savedStateSize = 0; - } - pthread_mutex_unlock(&android_app->mutex); -} - -int8_t android_app_read_cmd(struct android_app* android_app) { - int8_t cmd; - if (read(android_app->msgread, &cmd, sizeof(cmd)) == sizeof(cmd)) { - switch (cmd) { - case APP_CMD_SAVE_STATE: - free_saved_state(android_app); - break; - } - return cmd; - } else { - LOGE("No data on command pipe!"); - } - return -1; -} - -static void print_cur_config(struct android_app* android_app) { - char lang[2], country[2]; - AConfiguration_getLanguage(android_app->config, lang); - AConfiguration_getCountry(android_app->config, country); - - LOGV("Config: mcc=%d mnc=%d lang=%c%c cnt=%c%c orien=%d touch=%d dens=%d " - "keys=%d nav=%d keysHid=%d navHid=%d sdk=%d size=%d long=%d " - "modetype=%d modenight=%d", - AConfiguration_getMcc(android_app->config), - AConfiguration_getMnc(android_app->config), - lang[0], lang[1], country[0], country[1], - AConfiguration_getOrientation(android_app->config), - AConfiguration_getTouchscreen(android_app->config), - AConfiguration_getDensity(android_app->config), - AConfiguration_getKeyboard(android_app->config), - AConfiguration_getNavigation(android_app->config), - AConfiguration_getKeysHidden(android_app->config), - AConfiguration_getNavHidden(android_app->config), - AConfiguration_getSdkVersion(android_app->config), - AConfiguration_getScreenSize(android_app->config), - AConfiguration_getScreenLong(android_app->config), - AConfiguration_getUiModeType(android_app->config), - AConfiguration_getUiModeNight(android_app->config)); -} - -void android_app_pre_exec_cmd(struct android_app* android_app, int8_t cmd) { - switch (cmd) { - case APP_CMD_INPUT_CHANGED: - LOGV("APP_CMD_INPUT_CHANGED\n"); - pthread_mutex_lock(&android_app->mutex); - if (android_app->inputQueue != NULL) { - AInputQueue_detachLooper(android_app->inputQueue); - } - android_app->inputQueue = android_app->pendingInputQueue; - if (android_app->inputQueue != NULL) { - LOGV("Attaching input queue to looper"); - AInputQueue_attachLooper(android_app->inputQueue, - android_app->looper, LOOPER_ID_INPUT, NULL, - &android_app->inputPollSource); - } - pthread_cond_broadcast(&android_app->cond); - pthread_mutex_unlock(&android_app->mutex); - break; - - case APP_CMD_INIT_WINDOW: - LOGV("APP_CMD_INIT_WINDOW\n"); - pthread_mutex_lock(&android_app->mutex); - android_app->window = android_app->pendingWindow; - pthread_cond_broadcast(&android_app->cond); - pthread_mutex_unlock(&android_app->mutex); - break; - - case APP_CMD_TERM_WINDOW: - LOGV("APP_CMD_TERM_WINDOW\n"); - pthread_cond_broadcast(&android_app->cond); - break; - - case APP_CMD_RESUME: - case APP_CMD_START: - case APP_CMD_PAUSE: - case APP_CMD_STOP: - LOGV("activityState=%d\n", cmd); - pthread_mutex_lock(&android_app->mutex); - android_app->activityState = cmd; - pthread_cond_broadcast(&android_app->cond); - pthread_mutex_unlock(&android_app->mutex); - break; - - case APP_CMD_CONFIG_CHANGED: - LOGV("APP_CMD_CONFIG_CHANGED\n"); - AConfiguration_fromAssetManager(android_app->config, - android_app->activity->assetManager); - print_cur_config(android_app); - break; - - case APP_CMD_DESTROY: - LOGV("APP_CMD_DESTROY\n"); - android_app->destroyRequested = 1; - break; - } -} - -void android_app_post_exec_cmd(struct android_app* android_app, int8_t cmd) { - switch (cmd) { - case APP_CMD_TERM_WINDOW: - LOGV("APP_CMD_TERM_WINDOW\n"); - pthread_mutex_lock(&android_app->mutex); - android_app->window = NULL; - pthread_cond_broadcast(&android_app->cond); - pthread_mutex_unlock(&android_app->mutex); - break; - - case APP_CMD_SAVE_STATE: - LOGV("APP_CMD_SAVE_STATE\n"); - pthread_mutex_lock(&android_app->mutex); - android_app->stateSaved = 1; - pthread_cond_broadcast(&android_app->cond); - pthread_mutex_unlock(&android_app->mutex); - break; - - case APP_CMD_RESUME: - free_saved_state(android_app); - break; - } -} - -static void android_app_destroy(struct android_app* android_app) { - LOGV("android_app_destroy!"); - free_saved_state(android_app); - pthread_mutex_lock(&android_app->mutex); - if (android_app->inputQueue != NULL) { - AInputQueue_detachLooper(android_app->inputQueue); - } - AConfiguration_delete(android_app->config); - android_app->destroyed = 1; - pthread_cond_broadcast(&android_app->cond); - pthread_mutex_unlock(&android_app->mutex); - // Can't touch android_app object after this. -} - -static void process_input(struct android_app* app, struct android_poll_source* source) { - AInputEvent* event = NULL; - while (AInputQueue_getEvent(app->inputQueue, &event) >= 0) { - LOGV("New input event: type=%d\n", AInputEvent_getType(event)); - if (AInputQueue_preDispatchEvent(app->inputQueue, event)) { - continue; - } - int32_t handled = 0; - if (app->onInputEvent != NULL) handled = app->onInputEvent(app, event); - AInputQueue_finishEvent(app->inputQueue, event, handled); - } -} - -static void process_cmd(struct android_app* app, struct android_poll_source* source) { - int8_t cmd = android_app_read_cmd(app); - android_app_pre_exec_cmd(app, cmd); - if (app->onAppCmd != NULL) app->onAppCmd(app, cmd); - android_app_post_exec_cmd(app, cmd); -} - -static void* android_app_entry(void* param) { - struct android_app* android_app = (struct android_app*)param; - - android_app->config = AConfiguration_new(); - AConfiguration_fromAssetManager(android_app->config, android_app->activity->assetManager); - - print_cur_config(android_app); - - android_app->cmdPollSource.id = LOOPER_ID_MAIN; - android_app->cmdPollSource.app = android_app; - android_app->cmdPollSource.process = process_cmd; - android_app->inputPollSource.id = LOOPER_ID_INPUT; - android_app->inputPollSource.app = android_app; - android_app->inputPollSource.process = process_input; - - ALooper* looper = ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS); - ALooper_addFd(looper, android_app->msgread, LOOPER_ID_MAIN, ALOOPER_EVENT_INPUT, NULL, - &android_app->cmdPollSource); - android_app->looper = looper; - - pthread_mutex_lock(&android_app->mutex); - android_app->running = 1; - pthread_cond_broadcast(&android_app->cond); - pthread_mutex_unlock(&android_app->mutex); - - android_main(android_app); - - android_app_destroy(android_app); - return NULL; -} - -// -------------------------------------------------------------------- -// Native activity interaction (called from main thread) -// -------------------------------------------------------------------- - -static struct android_app* android_app_create(ANativeActivity* activity, - void* savedState, size_t savedStateSize) { - struct android_app* android_app = (struct android_app*)malloc(sizeof(struct android_app)); - memset(android_app, 0, sizeof(struct android_app)); - android_app->activity = activity; - - pthread_mutex_init(&android_app->mutex, NULL); - pthread_cond_init(&android_app->cond, NULL); - - if (savedState != NULL) { - android_app->savedState = malloc(savedStateSize); - android_app->savedStateSize = savedStateSize; - memcpy(android_app->savedState, savedState, savedStateSize); - } - - int msgpipe[2]; - if (pipe(msgpipe)) { - LOGE("could not create pipe: %s", strerror(errno)); - return NULL; - } - android_app->msgread = msgpipe[0]; - android_app->msgwrite = msgpipe[1]; - - pthread_attr_t attr; - pthread_attr_init(&attr); - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); - pthread_create(&android_app->thread, &attr, android_app_entry, android_app); - - // Wait for thread to start. - pthread_mutex_lock(&android_app->mutex); - while (!android_app->running) { - pthread_cond_wait(&android_app->cond, &android_app->mutex); - } - pthread_mutex_unlock(&android_app->mutex); - - return android_app; -} - -static void android_app_write_cmd(struct android_app* android_app, int8_t cmd) { - if (write(android_app->msgwrite, &cmd, sizeof(cmd)) != sizeof(cmd)) { - LOGE("Failure writing android_app cmd: %s\n", strerror(errno)); - } -} - -static void android_app_set_input(struct android_app* android_app, AInputQueue* inputQueue) { - pthread_mutex_lock(&android_app->mutex); - android_app->pendingInputQueue = inputQueue; - android_app_write_cmd(android_app, APP_CMD_INPUT_CHANGED); - while (android_app->inputQueue != android_app->pendingInputQueue) { - pthread_cond_wait(&android_app->cond, &android_app->mutex); - } - pthread_mutex_unlock(&android_app->mutex); -} - -static void android_app_set_window(struct android_app* android_app, ANativeWindow* window) { - pthread_mutex_lock(&android_app->mutex); - if (android_app->pendingWindow != NULL) { - android_app_write_cmd(android_app, APP_CMD_TERM_WINDOW); - } - android_app->pendingWindow = window; - if (window != NULL) { - android_app_write_cmd(android_app, APP_CMD_INIT_WINDOW); - } - while (android_app->window != android_app->pendingWindow) { - pthread_cond_wait(&android_app->cond, &android_app->mutex); - } - pthread_mutex_unlock(&android_app->mutex); -} - -static void android_app_set_activity_state(struct android_app* android_app, int8_t cmd) { - pthread_mutex_lock(&android_app->mutex); - android_app_write_cmd(android_app, cmd); - while (android_app->activityState != cmd) { - pthread_cond_wait(&android_app->cond, &android_app->mutex); - } - pthread_mutex_unlock(&android_app->mutex); -} - -static void android_app_free(struct android_app* android_app) { - pthread_mutex_lock(&android_app->mutex); - android_app_write_cmd(android_app, APP_CMD_DESTROY); - while (!android_app->destroyed) { - pthread_cond_wait(&android_app->cond, &android_app->mutex); - } - pthread_mutex_unlock(&android_app->mutex); - - close(android_app->msgread); - close(android_app->msgwrite); - pthread_cond_destroy(&android_app->cond); - pthread_mutex_destroy(&android_app->mutex); - free(android_app); -} - -static void onDestroy(ANativeActivity* activity) { - LOGV("Destroy: %p\n", activity); - android_app_free((struct android_app*)activity->instance); -} - -static void onStart(ANativeActivity* activity) { - LOGV("Start: %p\n", activity); - android_app_set_activity_state((struct android_app*)activity->instance, APP_CMD_START); -} - -static void onResume(ANativeActivity* activity) { - LOGV("Resume: %p\n", activity); - android_app_set_activity_state((struct android_app*)activity->instance, APP_CMD_RESUME); -} - -static void* onSaveInstanceState(ANativeActivity* activity, size_t* outLen) { - struct android_app* android_app = (struct android_app*)activity->instance; - void* savedState = NULL; - - LOGV("SaveInstanceState: %p\n", activity); - pthread_mutex_lock(&android_app->mutex); - android_app->stateSaved = 0; - android_app_write_cmd(android_app, APP_CMD_SAVE_STATE); - while (!android_app->stateSaved) { - pthread_cond_wait(&android_app->cond, &android_app->mutex); - } - - if (android_app->savedState != NULL) { - savedState = android_app->savedState; - *outLen = android_app->savedStateSize; - android_app->savedState = NULL; - android_app->savedStateSize = 0; - } - - pthread_mutex_unlock(&android_app->mutex); - - return savedState; -} - -static void onPause(ANativeActivity* activity) { - LOGV("Pause: %p\n", activity); - android_app_set_activity_state((struct android_app*)activity->instance, APP_CMD_PAUSE); -} - -static void onStop(ANativeActivity* activity) { - LOGV("Stop: %p\n", activity); - android_app_set_activity_state((struct android_app*)activity->instance, APP_CMD_STOP); -} - -static void onConfigurationChanged(ANativeActivity* activity) { - struct android_app* android_app = (struct android_app*)activity->instance; - LOGV("ConfigurationChanged: %p\n", activity); - android_app_write_cmd(android_app, APP_CMD_CONFIG_CHANGED); -} - -static void onLowMemory(ANativeActivity* activity) { - struct android_app* android_app = (struct android_app*)activity->instance; - LOGV("LowMemory: %p\n", activity); - android_app_write_cmd(android_app, APP_CMD_LOW_MEMORY); -} - -static void onWindowFocusChanged(ANativeActivity* activity, int focused) { - LOGV("WindowFocusChanged: %p -- %d\n", activity, focused); - android_app_write_cmd((struct android_app*)activity->instance, - focused ? APP_CMD_GAINED_FOCUS : APP_CMD_LOST_FOCUS); -} - -static void onNativeWindowCreated(ANativeActivity* activity, ANativeWindow* window) { - LOGV("NativeWindowCreated: %p -- %p\n", activity, window); - android_app_set_window((struct android_app*)activity->instance, window); -} - -static void onNativeWindowDestroyed(ANativeActivity* activity, ANativeWindow* window) { - LOGV("NativeWindowDestroyed: %p -- %p\n", activity, window); - android_app_set_window((struct android_app*)activity->instance, NULL); -} - -static void onInputQueueCreated(ANativeActivity* activity, AInputQueue* queue) { - LOGV("InputQueueCreated: %p -- %p\n", activity, queue); - android_app_set_input((struct android_app*)activity->instance, queue); -} - -static void onInputQueueDestroyed(ANativeActivity* activity, AInputQueue* queue) { - LOGV("InputQueueDestroyed: %p -- %p\n", activity, queue); - android_app_set_input((struct android_app*)activity->instance, NULL); -} - -void ANativeActivity_onCreate(ANativeActivity* activity, - void* savedState, size_t savedStateSize) { - LOGV("Creating: %p\n", activity); - activity->callbacks->onDestroy = onDestroy; - activity->callbacks->onStart = onStart; - activity->callbacks->onResume = onResume; - activity->callbacks->onSaveInstanceState = onSaveInstanceState; - activity->callbacks->onPause = onPause; - activity->callbacks->onStop = onStop; - activity->callbacks->onConfigurationChanged = onConfigurationChanged; - activity->callbacks->onLowMemory = onLowMemory; - activity->callbacks->onWindowFocusChanged = onWindowFocusChanged; - activity->callbacks->onNativeWindowCreated = onNativeWindowCreated; - activity->callbacks->onNativeWindowDestroyed = onNativeWindowDestroyed; - activity->callbacks->onInputQueueCreated = onInputQueueCreated; - activity->callbacks->onInputQueueDestroyed = onInputQueueDestroyed; - - activity->instance = android_app_create(activity, savedState, savedStateSize); -} diff --git a/android/computeparticles/computeparticles.NativeActivity/android_native_app_glue.h b/android/computeparticles/computeparticles.NativeActivity/android_native_app_glue.h deleted file mode 100644 index 1b390c2d..00000000 --- a/android/computeparticles/computeparticles.NativeActivity/android_native_app_glue.h +++ /dev/null @@ -1,344 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#ifndef _ANDROID_NATIVE_APP_GLUE_H -#define _ANDROID_NATIVE_APP_GLUE_H - -#include -#include -#include - -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * The native activity interface provided by - * is based on a set of application-provided callbacks that will be called - * by the Activity's main thread when certain events occur. - * - * This means that each one of this callbacks _should_ _not_ block, or they - * risk having the system force-close the application. This programming - * model is direct, lightweight, but constraining. - * - * The 'threaded_native_app' static library is used to provide a different - * execution model where the application can implement its own main event - * loop in a different thread instead. Here's how it works: - * - * 1/ The application must provide a function named "android_main()" that - * will be called when the activity is created, in a new thread that is - * distinct from the activity's main thread. - * - * 2/ android_main() receives a pointer to a valid "android_app" structure - * that contains references to other important objects, e.g. the - * ANativeActivity obejct instance the application is running in. - * - * 3/ the "android_app" object holds an ALooper instance that already - * listens to two important things: - * - * - activity lifecycle events (e.g. "pause", "resume"). See APP_CMD_XXX - * declarations below. - * - * - input events coming from the AInputQueue attached to the activity. - * - * Each of these correspond to an ALooper identifier returned by - * ALooper_pollOnce with values of LOOPER_ID_MAIN and LOOPER_ID_INPUT, - * respectively. - * - * Your application can use the same ALooper to listen to additional - * file-descriptors. They can either be callback based, or with return - * identifiers starting with LOOPER_ID_USER. - * - * 4/ Whenever you receive a LOOPER_ID_MAIN or LOOPER_ID_INPUT event, - * the returned data will point to an android_poll_source structure. You - * can call the process() function on it, and fill in android_app->onAppCmd - * and android_app->onInputEvent to be called for your own processing - * of the event. - * - * Alternatively, you can call the low-level functions to read and process - * the data directly... look at the process_cmd() and process_input() - * implementations in the glue to see how to do this. - * - * See the sample named "native-activity" that comes with the NDK with a - * full usage example. Also look at the JavaDoc of NativeActivity. - */ - -struct android_app; - -/** - * Data associated with an ALooper fd that will be returned as the "outData" - * when that source has data ready. - */ -struct android_poll_source { - // The identifier of this source. May be LOOPER_ID_MAIN or - // LOOPER_ID_INPUT. - int32_t id; - - // The android_app this ident is associated with. - struct android_app* app; - - // Function to call to perform the standard processing of data from - // this source. - void (*process)(struct android_app* app, struct android_poll_source* source); -}; - -/** - * This is the interface for the standard glue code of a threaded - * application. In this model, the application's code is running - * in its own thread separate from the main thread of the process. - * It is not required that this thread be associated with the Java - * VM, although it will need to be in order to make JNI calls any - * Java objects. - */ -struct android_app { - // The application can place a pointer to its own state object - // here if it likes. - void* userData; - - // Fill this in with the function to process main app commands (APP_CMD_*) - void (*onAppCmd)(struct android_app* app, int32_t cmd); - - // Fill this in with the function to process input events. At this point - // the event has already been pre-dispatched, and it will be finished upon - // return. Return 1 if you have handled the event, 0 for any default - // dispatching. - int32_t (*onInputEvent)(struct android_app* app, AInputEvent* event); - - // The ANativeActivity object instance that this app is running in. - ANativeActivity* activity; - - // The current configuration the app is running in. - AConfiguration* config; - - // This is the last instance's saved state, as provided at creation time. - // It is NULL if there was no state. You can use this as you need; the - // memory will remain around until you call android_app_exec_cmd() for - // APP_CMD_RESUME, at which point it will be freed and savedState set to NULL. - // These variables should only be changed when processing a APP_CMD_SAVE_STATE, - // at which point they will be initialized to NULL and you can malloc your - // state and place the information here. In that case the memory will be - // freed for you later. - void* savedState; - size_t savedStateSize; - - // The ALooper associated with the app's thread. - ALooper* looper; - - // When non-NULL, this is the input queue from which the app will - // receive user input events. - AInputQueue* inputQueue; - - // When non-NULL, this is the window surface that the app can draw in. - ANativeWindow* window; - - // Current content rectangle of the window; this is the area where the - // window's content should be placed to be seen by the user. - ARect contentRect; - - // Current state of the app's activity. May be either APP_CMD_START, - // APP_CMD_RESUME, APP_CMD_PAUSE, or APP_CMD_STOP; see below. - int activityState; - - // This is non-zero when the application's NativeActivity is being - // destroyed and waiting for the app thread to complete. - int destroyRequested; - - // ------------------------------------------------- - // Below are "private" implementation of the glue code. - - pthread_mutex_t mutex; - pthread_cond_t cond; - - int msgread; - int msgwrite; - - pthread_t thread; - - struct android_poll_source cmdPollSource; - struct android_poll_source inputPollSource; - - int running; - int stateSaved; - int destroyed; - int redrawNeeded; - AInputQueue* pendingInputQueue; - ANativeWindow* pendingWindow; - ARect pendingContentRect; -}; - -enum { - /** - * Looper data ID of commands coming from the app's main thread, which - * is returned as an identifier from ALooper_pollOnce(). The data for this - * identifier is a pointer to an android_poll_source structure. - * These can be retrieved and processed with android_app_read_cmd() - * and android_app_exec_cmd(). - */ - LOOPER_ID_MAIN = 1, - - /** - * Looper data ID of events coming from the AInputQueue of the - * application's window, which is returned as an identifier from - * ALooper_pollOnce(). The data for this identifier is a pointer to an - * android_poll_source structure. These can be read via the inputQueue - * object of android_app. - */ - LOOPER_ID_INPUT = 2, - - /** - * Start of user-defined ALooper identifiers. - */ - LOOPER_ID_USER = 3, -}; - -enum { - /** - * Command from main thread: the AInputQueue has changed. Upon processing - * this command, android_app->inputQueue will be updated to the new queue - * (or NULL). - */ - APP_CMD_INPUT_CHANGED, - - /** - * Command from main thread: a new ANativeWindow is ready for use. Upon - * receiving this command, android_app->window will contain the new window - * surface. - */ - APP_CMD_INIT_WINDOW, - - /** - * Command from main thread: the existing ANativeWindow needs to be - * terminated. Upon receiving this command, android_app->window still - * contains the existing window; after calling android_app_exec_cmd - * it will be set to NULL. - */ - APP_CMD_TERM_WINDOW, - - /** - * Command from main thread: the current ANativeWindow has been resized. - * Please redraw with its new size. - */ - APP_CMD_WINDOW_RESIZED, - - /** - * Command from main thread: the system needs that the current ANativeWindow - * be redrawn. You should redraw the window before handing this to - * android_app_exec_cmd() in order to avoid transient drawing glitches. - */ - APP_CMD_WINDOW_REDRAW_NEEDED, - - /** - * Command from main thread: the content area of the window has changed, - * such as from the soft input window being shown or hidden. You can - * find the new content rect in android_app::contentRect. - */ - APP_CMD_CONTENT_RECT_CHANGED, - - /** - * Command from main thread: the app's activity window has gained - * input focus. - */ - APP_CMD_GAINED_FOCUS, - - /** - * Command from main thread: the app's activity window has lost - * input focus. - */ - APP_CMD_LOST_FOCUS, - - /** - * Command from main thread: the current device configuration has changed. - */ - APP_CMD_CONFIG_CHANGED, - - /** - * Command from main thread: the system is running low on memory. - * Try to reduce your memory use. - */ - APP_CMD_LOW_MEMORY, - - /** - * Command from main thread: the app's activity has been started. - */ - APP_CMD_START, - - /** - * Command from main thread: the app's activity has been resumed. - */ - APP_CMD_RESUME, - - /** - * Command from main thread: the app should generate a new saved state - * for itself, to restore from later if needed. If you have saved state, - * allocate it with malloc and place it in android_app.savedState with - * the size in android_app.savedStateSize. The will be freed for you - * later. - */ - APP_CMD_SAVE_STATE, - - /** - * Command from main thread: the app's activity has been paused. - */ - APP_CMD_PAUSE, - - /** - * Command from main thread: the app's activity has been stopped. - */ - APP_CMD_STOP, - - /** - * Command from main thread: the app's activity is being destroyed, - * and waiting for the app thread to clean up and exit before proceeding. - */ - APP_CMD_DESTROY, -}; - -/** - * Call when ALooper_pollAll() returns LOOPER_ID_MAIN, reading the next - * app command message. - */ -int8_t android_app_read_cmd(struct android_app* android_app); - -/** - * Call with the command returned by android_app_read_cmd() to do the - * initial pre-processing of the given command. You can perform your own - * actions for the command after calling this function. - */ -void android_app_pre_exec_cmd(struct android_app* android_app, int8_t cmd); - -/** - * Call with the command returned by android_app_read_cmd() to do the - * final post-processing of the given command. You must have done your own - * actions for the command before calling this function. - */ -void android_app_post_exec_cmd(struct android_app* android_app, int8_t cmd); - -/** - * This is the function that application code must implement, representing - * the main entry to the app. - */ -extern void android_main(struct android_app* app); - -#ifdef __cplusplus -} -#endif - -#endif /* _ANDROID_NATIVE_APP_GLUE_H */ diff --git a/android/computeparticles/computeparticles.NativeActivity/computeparticles.NativeActivity.vcxproj b/android/computeparticles/computeparticles.NativeActivity/computeparticles.NativeActivity.vcxproj deleted file mode 100644 index 19b1070c..00000000 --- a/android/computeparticles/computeparticles.NativeActivity/computeparticles.NativeActivity.vcxproj +++ /dev/null @@ -1,224 +0,0 @@ - - - - - Debug - ARM - - - Release - ARM - - - Debug - ARM64 - - - Release - ARM64 - - - Debug - x64 - - - Release - x64 - - - Debug - x86 - - - Release - x86 - - - - {1C538546-0768-4071-81A6-86EE8F33AA1A} - Android - computeparticles - en-US - 14.0 - Android - 1.0 - - - - DynamicLibrary - true - Clang_3_6 - - - DynamicLibrary - false - Clang_3_6 - - - DynamicLibrary - true - Clang_3_6 - - - DynamicLibrary - false - Clang_3_6 - - - DynamicLibrary - true - Clang_3_6 - - - DynamicLibrary - false - Clang_3_6 - - - DynamicLibrary - true - Clang_3_6 - - - DynamicLibrary - false - Clang_3_6 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Use - pch.h - CompileAsCpp - - - %(LibraryDependencies);GLESv1_CM;EGL; - - - - - Use - pch.h - CompileAsCpp - - - %(LibraryDependencies);GLESv1_CM;EGL; - - - - - Use - pch.h - CompileAsCpp - VK_NO_PROTOTYPES;VK_USE_PLATFORM_ANDROID_KHR;__STDINT_LIMITS - c++11 - ../../../external;../../../base;../../../external/gli;../../../external/glm;../../base;%(AdditionalIncludeDirectories) - - - %(LibraryDependencies);GLESv1_CM;EGL; - -lm %(AdditionalOptions) - - - - - Use - pch.h - CompileAsCpp - - - %(LibraryDependencies);GLESv1_CM;EGL; - - - - - Use - pch.h - CompileAsCpp - - - %(LibraryDependencies);GLESv1_CM;EGL; - - - - - Use - pch.h - CompileAsCpp - - - %(LibraryDependencies);GLESv1_CM;EGL; - - - - - Use - pch.h - CompileAsCpp - - - %(LibraryDependencies);GLESv1_CM;EGL; - - - - - Use - pch.h - CompileAsCpp - - - %(LibraryDependencies);GLESv1_CM;EGL; - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/android/computeparticles/computeparticles.NativeActivity/computeparticles.NativeActivity.vcxproj.filters b/android/computeparticles/computeparticles.NativeActivity/computeparticles.NativeActivity.vcxproj.filters deleted file mode 100644 index 6ecf4947..00000000 --- a/android/computeparticles/computeparticles.NativeActivity/computeparticles.NativeActivity.vcxproj.filters +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/android/computeparticles/computeparticles.NativeActivity/computeparticles.cpp b/android/computeparticles/computeparticles.NativeActivity/computeparticles.cpp deleted file mode 100644 index 3b46e31c..00000000 --- a/android/computeparticles/computeparticles.NativeActivity/computeparticles.cpp +++ /dev/null @@ -1,822 +0,0 @@ -/* -* Vulkan Example - Compute shader particle system -* -* Note : -* This is a basic android example. It may be integrated into the other examples at some point in the future. -* Until then this serves as a starting point for using Vulkan on Android, with some of the functionality required -* already moved to the example base classes (e.g. swap chain) -* -* Copyright (C) 2016 by Sascha Willems - www.saschawillems.de -* -* This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) -*/ - -#include -#include "vulkanandroid.h" -#include "vulkanswapchain.hpp" -#include "vulkanandroidbase.hpp" -#include - -#define GLM_FORCE_RADIANS -#define GLM_FORCE_DEPTH_ZERO_TO_ONE -#include "glm/glm.hpp" -#include "glm/gtc/matrix_transform.hpp" - -#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "AndroidProject1.NativeActivity", __VA_ARGS__)) -#define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, "AndroidProject1.NativeActivity", __VA_ARGS__)) - -#define VERTEX_BUFFER_BIND_ID 0 -#define PARTICLE_COUNT 4 * 1024 - -struct saved_state { - glm::vec3 rotation; - float zoom; -}; - -struct VulkanExample : public VulkanAndroidExampleBase -{ -public: - int animating; - struct saved_state state; - - float timer = 0.0f; - float animStart = 50.0f; - bool animate = true; - - // Vulkan - struct Vertex { - float pos[3]; - float uv[2]; - }; - - Texture texture; - - VkDescriptorSetLayout descriptorSetLayout; - VkDescriptorSet descriptorSet; - VkPipelineLayout pipelineLayout; - - struct { - VkPipelineVertexInputStateCreateInfo inputState; - std::vector bindingDescriptions; - std::vector attributeDescriptions; - } vertices; - - struct { - VkPipeline solid; - VkPipeline compute; - } pipelines; - - VkQueue computeQueue; - VkCommandBuffer computeCmdBuffer; - VkPipelineLayout computePipelineLayout; - VkDescriptorSet computeDescriptorSet; - VkDescriptorSetLayout computeDescriptorSetLayout; - - vkTools::UniformData computeStorageBuffer; - - struct Particle { - glm::vec4 pos; - glm::vec4 col; - glm::vec4 vel; - }; - - struct { - float deltaT; - float destX; - float destY; - int32_t particleCount = PARTICLE_COUNT; - } computeUbo; - - vkTools::UniformData uniformDataCompute; - - void initVulkan() - { - VulkanAndroidExampleBase::initVulkan(); - - loadTexture( - "textures/android_robot.ktx", - VK_FORMAT_R8G8B8A8_UNORM, - &texture, - false); - - createCommandBuffers(); - - // Compute stuff - getComputeQueue(); - createComputeCommandBuffer(); - prepareStorageBuffers(); - - prepareUniformBuffers(); - setupDescriptorSetLayout(); - preparePipelines(); - setupDescriptorPool(); - setupDescriptorSet(); - - prepareCompute(); - - buildCommandBuffers(); - buildComputeCommandBuffer(); - - state.zoom = -5.0f; - state.rotation = glm::vec3(); - - prepared = true; - } - - void cleanupVulkan() - { - prepared = false; - vkDestroyPipeline(device, pipelines.solid, nullptr); - vkDestroyPipelineLayout(device, pipelineLayout, nullptr); - vkDestroyPipelineLayout(device, computePipelineLayout, nullptr); - vkDestroyDescriptorSetLayout(device, descriptorSetLayout, nullptr); - vkDestroyDescriptorSetLayout(device, computeDescriptorSetLayout, nullptr); - vkDestroyBuffer(device, uniformDataCompute.buffer, nullptr); - vkFreeMemory(device, uniformDataCompute.memory, nullptr); - vkDestroyBuffer(device, computeStorageBuffer.buffer, nullptr); - vkFreeMemory(device, computeStorageBuffer.memory, nullptr); - - destroyTextureImage(&texture); - - vkFreeCommandBuffers(device, cmdPool, 1, &computeCmdBuffer); - - VulkanExample::cleanUpVulkan(); - } - - // Find and create a compute capable device queue - void getComputeQueue() - { - uint32_t queueIndex = 0; - uint32_t queueCount; - vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueCount, NULL); - assert(queueCount >= 1); - - std::vector queueProps; - queueProps.resize(queueCount); - vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueCount, queueProps.data()); - - for (queueIndex = 0; queueIndex < queueCount; queueIndex++) - { - if (queueProps[queueIndex].queueFlags & VK_QUEUE_COMPUTE_BIT) - break; - } - assert(queueIndex < queueCount); - - VkDeviceQueueCreateInfo queueCreateInfo = {}; - queueCreateInfo.queueFamilyIndex = queueIndex; - queueCreateInfo.queueCount = 1; - vkGetDeviceQueue(device, queueIndex, 0, &computeQueue); - } - - void createComputeCommandBuffer() - { - VkCommandBufferAllocateInfo cmdBufAllocateInfo = - vkTools::initializers::commandBufferAllocateInfo( - cmdPool, - VK_COMMAND_BUFFER_LEVEL_PRIMARY, - 1); - - VkResult vkRes = vkAllocateCommandBuffers(device, &cmdBufAllocateInfo, &computeCmdBuffer); - assert(!vkRes); - } - - void buildComputeCommandBuffer() - { - VkCommandBufferBeginInfo cmdBufInfo = vkTools::initializers::commandBufferBeginInfo();; - - vkBeginCommandBuffer(computeCmdBuffer, &cmdBufInfo); - - vkCmdBindPipeline(computeCmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipelines.compute); - vkCmdBindDescriptorSets(computeCmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, computePipelineLayout, 0, 1, &computeDescriptorSet, 0, 0); - - vkCmdDispatch(computeCmdBuffer, PARTICLE_COUNT / 16, 1, 1); - - vkEndCommandBuffer(computeCmdBuffer); - } - - void updateUniformBuffers() - { - computeUbo.deltaT = (1.0f / frameTimer) * 0.15f; - computeUbo.destX = sin(glm::radians(timer*360.0)) * 0.75f; - computeUbo.destY = cos(glm::radians(timer*360.0)) * 0.10f; - uint8_t *pData; - VkResult err = vkMapMemory(device, uniformDataCompute.memory, 0, sizeof(computeUbo), 0, (void **)&pData); - assert(!err); - memcpy(pData, &computeUbo, sizeof(computeUbo)); - vkUnmapMemory(device, uniformDataCompute.memory); - } - - void prepareUniformBuffers() - { - // Prepare and initialize uniform buffer containing shader uniforms - VkMemoryRequirements memReqs; - - // Vertex shader uniform buffer block - VkBufferCreateInfo bufferInfo = {}; - VkMemoryAllocateInfo allocInfo = vkTools::initializers::memoryAllocateInfo(); - VkResult err; - - bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; - bufferInfo.size = sizeof(computeUbo); - bufferInfo.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; - - err = vkCreateBuffer(device, &bufferInfo, nullptr, &uniformDataCompute.buffer); - assert(!err); - vkGetBufferMemoryRequirements(device, uniformDataCompute.buffer, &memReqs); - allocInfo.allocationSize = memReqs.size; - getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, &allocInfo.memoryTypeIndex); - err = vkAllocateMemory(device, &allocInfo, nullptr, &(uniformDataCompute.memory)); - assert(!err); - err = vkBindBufferMemory(device, uniformDataCompute.buffer, uniformDataCompute.memory, 0); - assert(!err); - - uniformDataCompute.descriptor.buffer = uniformDataCompute.buffer; - uniformDataCompute.descriptor.offset = 0; - uniformDataCompute.descriptor.range = sizeof(computeUbo); - - updateUniformBuffers(); - } - - void preparePipelines() - { - VkResult err; - - VkPipelineInputAssemblyStateCreateInfo inputAssemblyState = - vkTools::initializers::pipelineInputAssemblyStateCreateInfo( - VK_PRIMITIVE_TOPOLOGY_POINT_LIST, - 0, - VK_FALSE); - - VkPipelineRasterizationStateCreateInfo rasterizationState = - vkTools::initializers::pipelineRasterizationStateCreateInfo( - VK_POLYGON_MODE_FILL, - VK_CULL_MODE_NONE, - VK_FRONT_FACE_COUNTER_CLOCKWISE, - 0); - - VkPipelineColorBlendAttachmentState blendAttachmentState = - vkTools::initializers::pipelineColorBlendAttachmentState( - 0xf, - VK_FALSE); - - VkPipelineColorBlendStateCreateInfo colorBlendState = - vkTools::initializers::pipelineColorBlendStateCreateInfo( - 1, - &blendAttachmentState); - - VkPipelineDepthStencilStateCreateInfo depthStencilState = - vkTools::initializers::pipelineDepthStencilStateCreateInfo( - VK_TRUE, - VK_TRUE, - VK_COMPARE_OP_LESS_OR_EQUAL); - - VkPipelineViewportStateCreateInfo viewportState = - vkTools::initializers::pipelineViewportStateCreateInfo(1, 1, 0); - - VkPipelineMultisampleStateCreateInfo multisampleState = - vkTools::initializers::pipelineMultisampleStateCreateInfo( - VK_SAMPLE_COUNT_1_BIT, - 0); - - std::vector dynamicStateEnables; - dynamicStateEnables.push_back(VK_DYNAMIC_STATE_VIEWPORT); - dynamicStateEnables.push_back(VK_DYNAMIC_STATE_SCISSOR); - - VkPipelineDynamicStateCreateInfo dynamicState = - vkTools::initializers::pipelineDynamicStateCreateInfo( - dynamicStateEnables.data(), - dynamicStateEnables.size(), - 0); - - // Rendering pipeline - // Load shaders - std::array shaderStages; - - shaderStages[0] = loadShader("shaders/particle.vert.spv", VK_SHADER_STAGE_VERTEX_BIT); - shaderStages[1] = loadShader("shaders/particle.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT); - - VkGraphicsPipelineCreateInfo pipelineCreateInfo = - vkTools::initializers::pipelineCreateInfo( - pipelineLayout, - renderPass, - 0); - - pipelineCreateInfo.pVertexInputState = &vertices.inputState; - pipelineCreateInfo.pInputAssemblyState = &inputAssemblyState; - pipelineCreateInfo.pRasterizationState = &rasterizationState; - pipelineCreateInfo.pColorBlendState = &colorBlendState; - pipelineCreateInfo.pMultisampleState = &multisampleState; - pipelineCreateInfo.pViewportState = &viewportState; - pipelineCreateInfo.pDepthStencilState = &depthStencilState; - pipelineCreateInfo.pDynamicState = &dynamicState; - pipelineCreateInfo.stageCount = shaderStages.size(); - pipelineCreateInfo.pStages = shaderStages.data(); - pipelineCreateInfo.renderPass = renderPass; - - // Additive blending - blendAttachmentState.blendEnable = VK_TRUE; - blendAttachmentState.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; - blendAttachmentState.colorBlendOp = VK_BLEND_OP_ADD; - blendAttachmentState.srcColorBlendFactor = VK_BLEND_FACTOR_ONE; - blendAttachmentState.dstColorBlendFactor = VK_BLEND_FACTOR_ONE; - blendAttachmentState.alphaBlendOp = VK_BLEND_OP_ADD; - blendAttachmentState.srcAlphaBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA; - blendAttachmentState.dstAlphaBlendFactor = VK_BLEND_FACTOR_DST_ALPHA; - - - err = vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.solid); - assert(!err); - } - - // Setup and fill the compute shader storage buffers for - // vertex positions and velocities - void prepareStorageBuffers() - { - float destPosX = 0.0f; - float destPosY = 0.0f; - - // Initial particle positions - std::vector particleBuffer; - for (int i = 0; i < PARTICLE_COUNT; ++i) - { - // Position - float aspectRatio = (float)height / (float)width; - float rndVal = (float)rand() / (float)(RAND_MAX / (360.0f * 3.14f * 2.0f)); - float rndRad = (float)rand() / (float)(RAND_MAX)* 0.65f; - Particle p; - p.pos = glm::vec4( - destPosX + cos(rndVal) * rndRad * aspectRatio, - destPosY + sin(rndVal) * rndRad, - 0.0f, - 1.0f); - p.col = glm::vec4( - (float)(rand() % 255) / 255.0f, - (float)(rand() % 255) / 255.0f, - (float)(rand() % 255) / 255.0f, - 1.0f); - p.vel = glm::vec4(0.0f); - particleBuffer.push_back(p); - } - - // Buffer size is the same for all storage buffers - uint32_t storageBufferSize = particleBuffer.size() * sizeof(Particle); - - VkMemoryAllocateInfo memAlloc = vkTools::initializers::memoryAllocateInfo(); - VkMemoryRequirements memReqs; - - VkResult err; - void *data; - - // Allocate and fill storage buffer object - VkBufferCreateInfo vBufferInfo = - vkTools::initializers::bufferCreateInfo( - VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, - storageBufferSize); - err = vkCreateBuffer(device, &vBufferInfo, nullptr, &computeStorageBuffer.buffer); - assert(!err); - vkGetBufferMemoryRequirements(device, computeStorageBuffer.buffer, &memReqs); - memAlloc.allocationSize = memReqs.size; - getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, &memAlloc.memoryTypeIndex); - err = vkAllocateMemory(device, &memAlloc, nullptr, &computeStorageBuffer.memory); - assert(!err); - err = vkMapMemory(device, computeStorageBuffer.memory, 0, storageBufferSize, 0, &data); - assert(!err); - memcpy(data, particleBuffer.data(), storageBufferSize); - vkUnmapMemory(device, computeStorageBuffer.memory); - err = vkBindBufferMemory(device, computeStorageBuffer.buffer, computeStorageBuffer.memory, 0); - assert(!err); - - computeStorageBuffer.descriptor.buffer = computeStorageBuffer.buffer; - computeStorageBuffer.descriptor.offset = 0; - computeStorageBuffer.descriptor.range = storageBufferSize; - - // Binding description - vertices.bindingDescriptions.resize(1); - vertices.bindingDescriptions[0] = - vkTools::initializers::vertexInputBindingDescription( - VERTEX_BUFFER_BIND_ID, - sizeof(Particle), - VK_VERTEX_INPUT_RATE_VERTEX); - - // Attribute descriptions - // Describes memory layout and shader positions - vertices.attributeDescriptions.resize(2); - // Location 0 : Position - vertices.attributeDescriptions[0] = - vkTools::initializers::vertexInputAttributeDescription( - VERTEX_BUFFER_BIND_ID, - 0, - VK_FORMAT_R32G32B32A32_SFLOAT, - 0); - // Location 1 : Color - vertices.attributeDescriptions[1] = - vkTools::initializers::vertexInputAttributeDescription( - VERTEX_BUFFER_BIND_ID, - 1, - VK_FORMAT_R32G32B32A32_SFLOAT, - sizeof(float) * 4); - - // Assign to vertex buffer - vertices.inputState = vkTools::initializers::pipelineVertexInputStateCreateInfo(); - vertices.inputState.vertexBindingDescriptionCount = vertices.bindingDescriptions.size(); - vertices.inputState.pVertexBindingDescriptions = vertices.bindingDescriptions.data(); - vertices.inputState.vertexAttributeDescriptionCount = vertices.attributeDescriptions.size(); - vertices.inputState.pVertexAttributeDescriptions = vertices.attributeDescriptions.data(); - } - - void prepareCompute() - { - // Create compute pipeline - // Compute pipelines are created separate from graphics pipelines - // even if they use the same queue - - std::vector setLayoutBindings; - setLayoutBindings.push_back( - // Binding 0 : Particle position storage buffer - vkTools::initializers::descriptorSetLayoutBinding( - VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, - VK_SHADER_STAGE_COMPUTE_BIT, - 0)); - setLayoutBindings.push_back( - // Binding 1 : Uniform buffer - vkTools::initializers::descriptorSetLayoutBinding( - VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, - VK_SHADER_STAGE_COMPUTE_BIT, - 1)); - - VkDescriptorSetLayoutCreateInfo descriptorLayout = - vkTools::initializers::descriptorSetLayoutCreateInfo( - setLayoutBindings.data(), - setLayoutBindings.size()); - - VkResult err = vkCreateDescriptorSetLayout( - device, - &descriptorLayout, - nullptr, - &computeDescriptorSetLayout); - assert(!err); - - VkPipelineLayoutCreateInfo pPipelineLayoutCreateInfo = - vkTools::initializers::pipelineLayoutCreateInfo( - &computeDescriptorSetLayout, - 1); - - err = vkCreatePipelineLayout( - device, - &pPipelineLayoutCreateInfo, - nullptr, - &computePipelineLayout); - assert(!err); - - VkDescriptorSetAllocateInfo allocInfo = - vkTools::initializers::descriptorSetAllocateInfo( - descriptorPool, - &computeDescriptorSetLayout, - 1); - - err = vkAllocateDescriptorSets(device, &allocInfo, &computeDescriptorSet); - assert(!err); - - std::vector computeWriteDescriptorSets; - computeWriteDescriptorSets.push_back( - // Binding 0 : Particle position storage buffer - vkTools::initializers::writeDescriptorSet( - computeDescriptorSet, - VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, - 0, - &computeStorageBuffer.descriptor)); - computeWriteDescriptorSets.push_back( - // Binding 1 : Uniform buffer - vkTools::initializers::writeDescriptorSet( - computeDescriptorSet, - VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, - 1, - &uniformDataCompute.descriptor)); - - vkUpdateDescriptorSets(device, computeWriteDescriptorSets.size(), computeWriteDescriptorSets.data(), 0, NULL); - - // Create pipeline - VkComputePipelineCreateInfo computePipelineCreateInfo = - vkTools::initializers::computePipelineCreateInfo( - computePipelineLayout, - 0); - computePipelineCreateInfo.stage = loadShader("shaders/particle.comp.spv", VK_SHADER_STAGE_COMPUTE_BIT); - - err = vkCreateComputePipelines(device, pipelineCache, 1, &computePipelineCreateInfo, nullptr, &pipelines.compute); - assert(!err); - } - - void setupDescriptorPool() - { - std::vector poolSizes; - poolSizes.push_back(vkTools::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1)); - poolSizes.push_back(vkTools::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1)); - poolSizes.push_back(vkTools::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1)); - - VkDescriptorPoolCreateInfo descriptorPoolInfo = - vkTools::initializers::descriptorPoolCreateInfo( - poolSizes.size(), - poolSizes.data(), - 2); - - VkResult vkRes = vkCreateDescriptorPool(device, &descriptorPoolInfo, nullptr, &descriptorPool); - assert(!vkRes); - } - - void setupDescriptorSetLayout() - { - std::vector setLayoutBindings; - setLayoutBindings.push_back( - // Binding 0 : Fragment shader image sampler - vkTools::initializers::descriptorSetLayoutBinding( - VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, - VK_SHADER_STAGE_FRAGMENT_BIT, - 0)); - - VkDescriptorSetLayoutCreateInfo descriptorLayout = - vkTools::initializers::descriptorSetLayoutCreateInfo( - setLayoutBindings.data(), - setLayoutBindings.size()); - - VkResult err = vkCreateDescriptorSetLayout(device, &descriptorLayout, nullptr, &descriptorSetLayout); - assert(!err); - - VkPipelineLayoutCreateInfo pPipelineLayoutCreateInfo = - vkTools::initializers::pipelineLayoutCreateInfo( - &descriptorSetLayout, - 1); - - err = vkCreatePipelineLayout(device, &pPipelineLayoutCreateInfo, nullptr, &pipelineLayout); - assert(!err); - } - - void setupDescriptorSet() - { - VkDescriptorSetAllocateInfo allocInfo = - vkTools::initializers::descriptorSetAllocateInfo( - descriptorPool, - &descriptorSetLayout, - 1); - - VkResult vkRes = vkAllocateDescriptorSets(device, &allocInfo, &descriptorSet); - assert(!vkRes); - - // Image descriptor for the color map texture - VkDescriptorImageInfo texDescriptor = - vkTools::initializers::descriptorImageInfo( - texture.sampler, - texture.view, - VK_IMAGE_LAYOUT_GENERAL); - - std::vector writeDescriptorSets; - writeDescriptorSets.push_back( - // Binding 0 : Fragment shader texture sampler - vkTools::initializers::writeDescriptorSet( - descriptorSet, - VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, - 0, - &texDescriptor)); - - vkUpdateDescriptorSets(device, writeDescriptorSets.size(), writeDescriptorSets.data(), 0, NULL); - } - - void buildCommandBuffers() - { - VkCommandBufferBeginInfo cmdBufInfo = vkTools::initializers::commandBufferBeginInfo(); - - VkClearValue clearValues[2]; - clearValues[0].color = { { 0.0f, 0.0f, 0.0f, 0.0f } }; - clearValues[1].depthStencil = { 1.0f, 0 }; - - VkRenderPassBeginInfo renderPassBeginInfo = vkTools::initializers::renderPassBeginInfo(); - renderPassBeginInfo.renderPass = renderPass; - renderPassBeginInfo.renderArea.offset.x = 0; - renderPassBeginInfo.renderArea.offset.y = 0; - renderPassBeginInfo.renderArea.extent.width = width; - renderPassBeginInfo.renderArea.extent.height = height; - renderPassBeginInfo.clearValueCount = 2; - renderPassBeginInfo.pClearValues = clearValues; - - VkResult err; - - for (int32_t i = 0; i < drawCmdBuffers.size(); ++i) - { - // Set target frame buffer - renderPassBeginInfo.framebuffer = frameBuffers[i]; - - err = vkBeginCommandBuffer(drawCmdBuffers[i], &cmdBufInfo); - assert(!err); - - // Buffer memory barrier to make sure that compute shader - // writes are finished before using the storage buffer - // in the vertex shader - VkBufferMemoryBarrier bufferBarrier = vkTools::initializers::bufferMemoryBarrier(); - // Source access : Compute shader buffer write - bufferBarrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT; - // Dest access : Vertex shader access (attribute binding) - bufferBarrier.dstAccessMask = VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT; - bufferBarrier.buffer = computeStorageBuffer.buffer; - bufferBarrier.offset = 0; - bufferBarrier.size = computeStorageBuffer.descriptor.range; - bufferBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; - bufferBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; - - vkCmdPipelineBarrier( - drawCmdBuffers[i], - VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, - VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, - VK_FLAGS_NONE, - 0, nullptr, - 1, &bufferBarrier, - 0, nullptr); - - vkCmdBeginRenderPass(drawCmdBuffers[i], &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); - - VkViewport viewport = vkTools::initializers::viewport( - (float)width, - (float)height, - 0.0f, - 1.0f - ); - vkCmdSetViewport(drawCmdBuffers[i], 0, 1, &viewport); - - VkRect2D scissor = vkTools::initializers::rect2D( - width, - height, - 0, - 0 - ); - vkCmdSetScissor(drawCmdBuffers[i], 0, 1, &scissor); - - vkCmdBindDescriptorSets(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &descriptorSet, 0, NULL); - vkCmdBindPipeline(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelines.solid); - - VkDeviceSize offsets[1] = { 0 }; - vkCmdBindVertexBuffers(drawCmdBuffers[i], VERTEX_BUFFER_BIND_ID, 1, &computeStorageBuffer.buffer, offsets); - vkCmdDraw(drawCmdBuffers[i], PARTICLE_COUNT, 1, 0, 0); - - vkCmdEndRenderPass(drawCmdBuffers[i]); - - VkImageMemoryBarrier prePresentBarrier = vkTools::prePresentBarrier(swapChain.buffers[i].image); - vkCmdPipelineBarrier( - drawCmdBuffers[i], - VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, - VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, - VK_FLAGS_NONE, - 0, nullptr, - 0, nullptr, - 1, &prePresentBarrier); - - err = vkEndCommandBuffer(drawCmdBuffers[i]); - assert(!err); - } - } - - void draw() - { - VkResult err; - - // Get next image in the swap chain (back/front buffer) - err = swapChain.acquireNextImage(semaphores.presentComplete, ¤tBuffer); - assert(!err); - - submitPostPresentBarrier(swapChain.buffers[currentBuffer].image); - - VkPipelineStageFlags pipelineStages = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; - VkSubmitInfo submitInfo = vkTools::initializers::submitInfo(); - submitInfo.waitSemaphoreCount = 1; - submitInfo.pWaitSemaphores = &semaphores.presentComplete; - submitInfo.commandBufferCount = 1; - submitInfo.pCommandBuffers = &drawCmdBuffers[currentBuffer]; - submitInfo.pWaitDstStageMask = &pipelineStages; - submitInfo.signalSemaphoreCount = 1; - submitInfo.pSignalSemaphores = &semaphores.submitSignal; - - // Submit to the graphics queue - err = vkQueueSubmit(queue, 1, &submitInfo, VK_NULL_HANDLE); - assert(!err); - - submitPrePresentBarrier(swapChain.buffers[currentBuffer].image); - - // Present the current buffer to the swap chain - // This will display the image - err = swapChain.queuePresent(queue, currentBuffer, semaphores.submitSignal); - assert(!err); - - // Compute - VkSubmitInfo computeSubmitInfo = vkTools::initializers::submitInfo(); - computeSubmitInfo.commandBufferCount = 1; - computeSubmitInfo.pCommandBuffers = &computeCmdBuffer; - - err = vkQueueSubmit(computeQueue, 1, &computeSubmitInfo, VK_NULL_HANDLE); - assert(!err); - - err = vkQueueWaitIdle(computeQueue); - assert(!err); - } - - void render() - { - // Render frame - if (prepared) - { - startTiming(); - if (animating) - { - if (animStart > 0.0f) - { - animStart -= 0.15f * (1.0f / frameTimer); - } - if ((animate) & (animStart <= 0.0f)) - { - timer += 0.5f * (1.0f / frameTimer); - if (timer > 1.0) - { - timer -= 1.0f; - } - } - updateUniformBuffers(); - } - draw(); - endTiming(); - } - } - -}; - -static int32_t handleInput(struct android_app* app, AInputEvent* event) -{ - struct VulkanExample* vulkanExample = (struct VulkanExample*)app->userData; - if (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_MOTION) - { - // todo - return 1; - } - return 0; -} - -static void handleCommand(struct android_app* app, int32_t cmd) -{ - VulkanExample* vulkanExample = (VulkanExample*)app->userData; - switch (cmd) - { - case APP_CMD_SAVE_STATE: - vulkanExample->app->savedState = malloc(sizeof(struct saved_state)); - *((struct saved_state*)vulkanExample->app->savedState) = vulkanExample->state; - vulkanExample->app->savedStateSize = sizeof(struct saved_state); - break; - case APP_CMD_INIT_WINDOW: - if (vulkanExample->app->window != NULL) - { - vulkanExample->initVulkan(); - assert(vulkanExample->prepared); - } - break; - case APP_CMD_LOST_FOCUS: - vulkanExample->animating = 0; - break; - } -} - -/** -* This is the main entry point of a native application that is using -* android_native_app_glue. It runs in its own thread, with its own -* event loop for receiving input events and doing other things. -*/ -void android_main(struct android_app* state) -{ - VulkanExample *engine = new VulkanExample(); - - state->userData = engine; - state->onAppCmd = handleCommand; - state->onInputEvent = handleInput; - engine->app = state; - - engine->animating = 1; - - // loop waiting for stuff to do. - - while (1) - { - // Read all pending events. - int ident; - int events; - struct android_poll_source* source; - - while ((ident = ALooper_pollAll(engine->animating ? 0 : -1, NULL, &events, (void**)&source)) >= 0) - { - if (source != NULL) - { - source->process(state, source); - } - - if (state->destroyRequested != 0) - { - engine->cleanupVulkan(); - return; - } - } - - engine->render(); - } -} diff --git a/android/computeparticles/computeparticles.NativeActivity/pch.h b/android/computeparticles/computeparticles.NativeActivity/pch.h deleted file mode 100644 index 487822aa..00000000 --- a/android/computeparticles/computeparticles.NativeActivity/pch.h +++ /dev/null @@ -1,22 +0,0 @@ -// -// pch.h -// Header for standard system include files. -// -// Used by the build system to generate the precompiled header. Note that no -// pch.cpp is needed and the pch.h is automatically included in all cpp files -// that are part of the project -// - -#include -#include - -#include -#include -#include - -#include "gli/gli.hpp" - -#include - -#include -#include "android_native_app_glue.h" diff --git a/android/computeparticles/computeparticles.Packaging/AndroidManifest.xml b/android/computeparticles/computeparticles.Packaging/AndroidManifest.xml deleted file mode 100644 index 61155b5f..00000000 --- a/android/computeparticles/computeparticles.Packaging/AndroidManifest.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/android/computeparticles/computeparticles.Packaging/assets/shaders/particle.comp.spv b/android/computeparticles/computeparticles.Packaging/assets/shaders/particle.comp.spv deleted file mode 100644 index cbeab76a..00000000 Binary files a/android/computeparticles/computeparticles.Packaging/assets/shaders/particle.comp.spv and /dev/null differ diff --git a/android/computeparticles/computeparticles.Packaging/assets/shaders/particle.frag.spv b/android/computeparticles/computeparticles.Packaging/assets/shaders/particle.frag.spv deleted file mode 100644 index fef7073e..00000000 Binary files a/android/computeparticles/computeparticles.Packaging/assets/shaders/particle.frag.spv and /dev/null differ diff --git a/android/computeparticles/computeparticles.Packaging/assets/shaders/particle.vert.spv b/android/computeparticles/computeparticles.Packaging/assets/shaders/particle.vert.spv deleted file mode 100644 index d1d41eed..00000000 Binary files a/android/computeparticles/computeparticles.Packaging/assets/shaders/particle.vert.spv and /dev/null differ diff --git a/android/computeparticles/computeparticles.Packaging/assets/textures/android_robot.ktx b/android/computeparticles/computeparticles.Packaging/assets/textures/android_robot.ktx deleted file mode 100644 index f5cd6faa..00000000 Binary files a/android/computeparticles/computeparticles.Packaging/assets/textures/android_robot.ktx and /dev/null differ diff --git a/android/computeparticles/computeparticles.Packaging/build.xml b/android/computeparticles/computeparticles.Packaging/build.xml deleted file mode 100644 index 0abadec5..00000000 --- a/android/computeparticles/computeparticles.Packaging/build.xml +++ /dev/null @@ -1,90 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/android/computeparticles/computeparticles.Packaging/computeparticles.Packaging.androidproj b/android/computeparticles/computeparticles.Packaging/computeparticles.Packaging.androidproj deleted file mode 100644 index 688ae811..00000000 --- a/android/computeparticles/computeparticles.Packaging/computeparticles.Packaging.androidproj +++ /dev/null @@ -1,135 +0,0 @@ - - - - - Debug - ARM - - - Release - ARM - - - Debug - ARM64 - - - Release - ARM64 - - - Debug - x64 - - - Release - x64 - - - Debug - x86 - - - Release - x86 - - - - computeparticles - 14.0 - 1.0 - 07b432c0-5242-4eb4-982b-ca895d032ae5 - - - - true - - - false - - - true - android-21 - - - false - - - true - - - false - - - true - - - false - - - - - - - $(SolutionDir)$(Platform)\$(Configuration)\$(RootNamespace) - - - - $(RootNamespace) - - - - - $(RootNamespace) - - - - - $(RootNamespace) - - - - - $(RootNamespace) - - - - - $(RootNamespace) - - - - - $(RootNamespace) - - - - - $(RootNamespace) - - - - - $(RootNamespace) - - - - - - - - - - - - - - - - - {622593a1-7b0d-4d71-8369-371601b8bee1} - - - - - \ No newline at end of file diff --git a/android/computeparticles/computeparticles.Packaging/project.properties b/android/computeparticles/computeparticles.Packaging/project.properties deleted file mode 100644 index 802a49f6..00000000 --- a/android/computeparticles/computeparticles.Packaging/project.properties +++ /dev/null @@ -1,3 +0,0 @@ -# Project target -target=$(androidapilevel) -# Provide path to the directory where prebuilt external jar files are by setting jar.libs.dir= diff --git a/android/computeparticles/computeparticles.Packaging/res/drawable/banner.png b/android/computeparticles/computeparticles.Packaging/res/drawable/banner.png deleted file mode 100644 index b9e715af..00000000 Binary files a/android/computeparticles/computeparticles.Packaging/res/drawable/banner.png and /dev/null differ diff --git a/android/computeparticles/computeparticles.Packaging/res/drawable/icon.png b/android/computeparticles/computeparticles.Packaging/res/drawable/icon.png deleted file mode 100644 index 40873575..00000000 Binary files a/android/computeparticles/computeparticles.Packaging/res/drawable/icon.png and /dev/null differ diff --git a/android/computeparticles/computeparticles.Packaging/res/values/strings.xml b/android/computeparticles/computeparticles.Packaging/res/values/strings.xml deleted file mode 100644 index 06b17e54..00000000 --- a/android/computeparticles/computeparticles.Packaging/res/values/strings.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - VulkanComputeExample - diff --git a/android/computeparticles/jni/Android.mk b/android/computeparticles/jni/Android.mk new file mode 100644 index 00000000..2a1b42bb --- /dev/null +++ b/android/computeparticles/jni/Android.mk @@ -0,0 +1,47 @@ +LOCAL_PATH := $(call my-dir)/../../computeparticles + +# assimp + +include $(CLEAR_VARS) + +LOCAL_MODULE := assimp +LOCAL_SRC_FILES := $(LOCAL_PATH)/../../libs/assimp/$(TARGET_ARCH_ABI)/libassimp.a +include $(PREBUILT_STATIC_LIBRARY) + +# vulkan example + +DATADIR := $(LOCAL_PATH)/../../data + +include $(CLEAR_VARS) + +LOCAL_MODULE := vulkanComputeparticles + +PROJECT_FILES := $(wildcard $(LOCAL_PATH)/../../computeparticles/*.cpp) +PROJECT_FILES += $(wildcard $(LOCAL_PATH)/../../base/*.cpp) + +LOCAL_CPPFLAGS := -std=c++11 +LOCAL_CPPFLAGS += -D__STDC_LIMIT_MACROS +LOCAL_CPPFLAGS += -DVK_NO_PROTOTYPES +LOCAL_CPPFLAGS += -DVK_USE_PLATFORM_ANDROID_KHR + +LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../external/ +LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../external/glm +LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../external/gli +LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../external/assimp +LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../base/ +#LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../base/android + +LOCAL_SRC_FILES := $(PROJECT_FILES) + +LOCAL_LDLIBS := -landroid -llog -lz + +LOCAL_DISABLE_FORMAT_STRING_CHECKS := true + +LOCAL_STATIC_LIBRARIES += android_native_app_glue +LOCAL_STATIC_LIBRARIES += cpufeatures +LOCAL_STATIC_LIBRARIES += libassimp + +include $(BUILD_SHARED_LIBRARY) + +$(call import-module, android/native_app_glue) +$(call import-module, android/cpufeatures) diff --git a/android/computeparticles/jni/Application.mk b/android/computeparticles/jni/Application.mk new file mode 100644 index 00000000..62020feb --- /dev/null +++ b/android/computeparticles/jni/Application.mk @@ -0,0 +1,5 @@ +APP_PLATFORM := android-19 +APP_ABI := armeabi-v7a +APP_STL := c++_static +APP_CPPFLAGS := -std=c++11 +NDK_TOOLCHAIN_VERSION := clang diff --git a/android/vulkanAndroid.sln b/android/vulkanAndroid.sln deleted file mode 100644 index 91beed81..00000000 --- a/android/vulkanAndroid.sln +++ /dev/null @@ -1,216 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 14 -VisualStudioVersion = 14.0.24720.0 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "triangle", "triangle", "{1E7F5677-399F-4C32-B47D-F6497CEC8977}" -EndProject -Project("{39E2626F-3545-4960-A6E8-258AD8476CE5}") = "triangle.Packaging", "triangle\triangle.Packaging\triangle.Packaging.androidproj", "{740E3731-7142-4CC6-931A-32FF8D672FCA}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "triangle.NativeActivity", "triangle\triangle.NativeActivity\triangle.NativeActivity.vcxproj", "{622593A1-7B0D-4D71-8369-371601B8BEE1}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "texture", "texture", "{DE733C33-3FDC-4164-9FFA-65515BC9FBAB}" -EndProject -Project("{39E2626F-3545-4960-A6E8-258AD8476CE5}") = "texture.Packaging", "texture\texture.Packaging\texture.Packaging.androidproj", "{46AAFC56-77C9-4666-B7C0-959B9A6C3400}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "texture.NativeActivity", "texture\texture.NativeActivity\texture.NativeActivity.vcxproj", "{1A536FCE-940C-4184-86A7-808AC521B3C3}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "computeparticles", "computeparticles", "{DA3A5B44-6038-4656-A8B9-22944BD2917D}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "computeparticles.NativeActivity", "computeparticles\computeparticles.NativeActivity\computeparticles.NativeActivity.vcxproj", "{1C538546-0768-4071-81A6-86EE8F33AA1A}" -EndProject -Project("{39E2626F-3545-4960-A6E8-258AD8476CE5}") = "computeparticles.Packaging", "computeparticles\computeparticles.Packaging\computeparticles.Packaging.androidproj", "{07B432C0-5242-4EB4-982B-CA895D032AE5}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "mesh", "mesh", "{8E46E97F-B3AB-45B1-9C90-876A8D7C7DB6}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mesh.NativeActivity", "mesh\mesh.NativeActivity\mesh.NativeActivity.vcxproj", "{18423C3F-1E8D-4D48-829D-554EFAD2F17E}" -EndProject -Project("{39E2626F-3545-4960-A6E8-258AD8476CE5}") = "mesh.Packaging", "mesh\mesh.Packaging\mesh.Packaging.androidproj", "{BAB95B1F-293D-440D-B19F-95FBFA3AA6EF}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|ARM = Debug|ARM - Debug|ARM64 = Debug|ARM64 - Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 - Release|ARM = Release|ARM - Release|ARM64 = Release|ARM64 - Release|x64 = Release|x64 - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {740E3731-7142-4CC6-931A-32FF8D672FCA}.Debug|ARM.ActiveCfg = Debug|ARM - {740E3731-7142-4CC6-931A-32FF8D672FCA}.Debug|ARM.Build.0 = Debug|ARM - {740E3731-7142-4CC6-931A-32FF8D672FCA}.Debug|ARM.Deploy.0 = Debug|ARM - {740E3731-7142-4CC6-931A-32FF8D672FCA}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {740E3731-7142-4CC6-931A-32FF8D672FCA}.Debug|ARM64.Build.0 = Debug|ARM64 - {740E3731-7142-4CC6-931A-32FF8D672FCA}.Debug|ARM64.Deploy.0 = Debug|ARM64 - {740E3731-7142-4CC6-931A-32FF8D672FCA}.Debug|x64.ActiveCfg = Debug|x64 - {740E3731-7142-4CC6-931A-32FF8D672FCA}.Debug|x64.Build.0 = Debug|x64 - {740E3731-7142-4CC6-931A-32FF8D672FCA}.Debug|x64.Deploy.0 = Debug|x64 - {740E3731-7142-4CC6-931A-32FF8D672FCA}.Debug|x86.ActiveCfg = Debug|x86 - {740E3731-7142-4CC6-931A-32FF8D672FCA}.Debug|x86.Build.0 = Debug|x86 - {740E3731-7142-4CC6-931A-32FF8D672FCA}.Debug|x86.Deploy.0 = Debug|x86 - {740E3731-7142-4CC6-931A-32FF8D672FCA}.Release|ARM.ActiveCfg = Release|ARM - {740E3731-7142-4CC6-931A-32FF8D672FCA}.Release|ARM.Build.0 = Release|ARM - {740E3731-7142-4CC6-931A-32FF8D672FCA}.Release|ARM.Deploy.0 = Release|ARM - {740E3731-7142-4CC6-931A-32FF8D672FCA}.Release|ARM64.ActiveCfg = Release|ARM64 - {740E3731-7142-4CC6-931A-32FF8D672FCA}.Release|ARM64.Build.0 = Release|ARM64 - {740E3731-7142-4CC6-931A-32FF8D672FCA}.Release|ARM64.Deploy.0 = Release|ARM64 - {740E3731-7142-4CC6-931A-32FF8D672FCA}.Release|x64.ActiveCfg = Release|x64 - {740E3731-7142-4CC6-931A-32FF8D672FCA}.Release|x64.Build.0 = Release|x64 - {740E3731-7142-4CC6-931A-32FF8D672FCA}.Release|x64.Deploy.0 = Release|x64 - {740E3731-7142-4CC6-931A-32FF8D672FCA}.Release|x86.ActiveCfg = Release|x86 - {740E3731-7142-4CC6-931A-32FF8D672FCA}.Release|x86.Build.0 = Release|x86 - {740E3731-7142-4CC6-931A-32FF8D672FCA}.Release|x86.Deploy.0 = Release|x86 - {622593A1-7B0D-4D71-8369-371601B8BEE1}.Debug|ARM.ActiveCfg = Debug|ARM - {622593A1-7B0D-4D71-8369-371601B8BEE1}.Debug|ARM.Build.0 = Debug|ARM - {622593A1-7B0D-4D71-8369-371601B8BEE1}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {622593A1-7B0D-4D71-8369-371601B8BEE1}.Debug|ARM64.Build.0 = Debug|ARM64 - {622593A1-7B0D-4D71-8369-371601B8BEE1}.Debug|x64.ActiveCfg = Debug|x64 - {622593A1-7B0D-4D71-8369-371601B8BEE1}.Debug|x64.Build.0 = Debug|x64 - {622593A1-7B0D-4D71-8369-371601B8BEE1}.Debug|x86.ActiveCfg = Debug|x86 - {622593A1-7B0D-4D71-8369-371601B8BEE1}.Debug|x86.Build.0 = Debug|x86 - {622593A1-7B0D-4D71-8369-371601B8BEE1}.Release|ARM.ActiveCfg = Release|ARM - {622593A1-7B0D-4D71-8369-371601B8BEE1}.Release|ARM.Build.0 = Release|ARM - {622593A1-7B0D-4D71-8369-371601B8BEE1}.Release|ARM64.ActiveCfg = Release|ARM64 - {622593A1-7B0D-4D71-8369-371601B8BEE1}.Release|ARM64.Build.0 = Release|ARM64 - {622593A1-7B0D-4D71-8369-371601B8BEE1}.Release|x64.ActiveCfg = Release|x64 - {622593A1-7B0D-4D71-8369-371601B8BEE1}.Release|x64.Build.0 = Release|x64 - {622593A1-7B0D-4D71-8369-371601B8BEE1}.Release|x86.ActiveCfg = Release|x86 - {622593A1-7B0D-4D71-8369-371601B8BEE1}.Release|x86.Build.0 = Release|x86 - {46AAFC56-77C9-4666-B7C0-959B9A6C3400}.Debug|ARM.ActiveCfg = Debug|ARM - {46AAFC56-77C9-4666-B7C0-959B9A6C3400}.Debug|ARM.Build.0 = Debug|ARM - {46AAFC56-77C9-4666-B7C0-959B9A6C3400}.Debug|ARM.Deploy.0 = Debug|ARM - {46AAFC56-77C9-4666-B7C0-959B9A6C3400}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {46AAFC56-77C9-4666-B7C0-959B9A6C3400}.Debug|ARM64.Build.0 = Debug|ARM64 - {46AAFC56-77C9-4666-B7C0-959B9A6C3400}.Debug|ARM64.Deploy.0 = Debug|ARM64 - {46AAFC56-77C9-4666-B7C0-959B9A6C3400}.Debug|x64.ActiveCfg = Debug|x64 - {46AAFC56-77C9-4666-B7C0-959B9A6C3400}.Debug|x64.Build.0 = Debug|x64 - {46AAFC56-77C9-4666-B7C0-959B9A6C3400}.Debug|x64.Deploy.0 = Debug|x64 - {46AAFC56-77C9-4666-B7C0-959B9A6C3400}.Debug|x86.ActiveCfg = Debug|x86 - {46AAFC56-77C9-4666-B7C0-959B9A6C3400}.Debug|x86.Build.0 = Debug|x86 - {46AAFC56-77C9-4666-B7C0-959B9A6C3400}.Debug|x86.Deploy.0 = Debug|x86 - {46AAFC56-77C9-4666-B7C0-959B9A6C3400}.Release|ARM.ActiveCfg = Release|ARM - {46AAFC56-77C9-4666-B7C0-959B9A6C3400}.Release|ARM.Build.0 = Release|ARM - {46AAFC56-77C9-4666-B7C0-959B9A6C3400}.Release|ARM.Deploy.0 = Release|ARM - {46AAFC56-77C9-4666-B7C0-959B9A6C3400}.Release|ARM64.ActiveCfg = Release|ARM64 - {46AAFC56-77C9-4666-B7C0-959B9A6C3400}.Release|ARM64.Build.0 = Release|ARM64 - {46AAFC56-77C9-4666-B7C0-959B9A6C3400}.Release|ARM64.Deploy.0 = Release|ARM64 - {46AAFC56-77C9-4666-B7C0-959B9A6C3400}.Release|x64.ActiveCfg = Release|x64 - {46AAFC56-77C9-4666-B7C0-959B9A6C3400}.Release|x64.Build.0 = Release|x64 - {46AAFC56-77C9-4666-B7C0-959B9A6C3400}.Release|x64.Deploy.0 = Release|x64 - {46AAFC56-77C9-4666-B7C0-959B9A6C3400}.Release|x86.ActiveCfg = Release|x86 - {46AAFC56-77C9-4666-B7C0-959B9A6C3400}.Release|x86.Build.0 = Release|x86 - {46AAFC56-77C9-4666-B7C0-959B9A6C3400}.Release|x86.Deploy.0 = Release|x86 - {1A536FCE-940C-4184-86A7-808AC521B3C3}.Debug|ARM.ActiveCfg = Debug|ARM - {1A536FCE-940C-4184-86A7-808AC521B3C3}.Debug|ARM.Build.0 = Debug|ARM - {1A536FCE-940C-4184-86A7-808AC521B3C3}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {1A536FCE-940C-4184-86A7-808AC521B3C3}.Debug|ARM64.Build.0 = Debug|ARM64 - {1A536FCE-940C-4184-86A7-808AC521B3C3}.Debug|x64.ActiveCfg = Debug|x64 - {1A536FCE-940C-4184-86A7-808AC521B3C3}.Debug|x64.Build.0 = Debug|x64 - {1A536FCE-940C-4184-86A7-808AC521B3C3}.Debug|x86.ActiveCfg = Debug|x86 - {1A536FCE-940C-4184-86A7-808AC521B3C3}.Debug|x86.Build.0 = Debug|x86 - {1A536FCE-940C-4184-86A7-808AC521B3C3}.Release|ARM.ActiveCfg = Release|ARM - {1A536FCE-940C-4184-86A7-808AC521B3C3}.Release|ARM.Build.0 = Release|ARM - {1A536FCE-940C-4184-86A7-808AC521B3C3}.Release|ARM64.ActiveCfg = Release|ARM64 - {1A536FCE-940C-4184-86A7-808AC521B3C3}.Release|ARM64.Build.0 = Release|ARM64 - {1A536FCE-940C-4184-86A7-808AC521B3C3}.Release|x64.ActiveCfg = Release|x64 - {1A536FCE-940C-4184-86A7-808AC521B3C3}.Release|x64.Build.0 = Release|x64 - {1A536FCE-940C-4184-86A7-808AC521B3C3}.Release|x86.ActiveCfg = Release|x86 - {1A536FCE-940C-4184-86A7-808AC521B3C3}.Release|x86.Build.0 = Release|x86 - {1C538546-0768-4071-81A6-86EE8F33AA1A}.Debug|ARM.ActiveCfg = Debug|ARM - {1C538546-0768-4071-81A6-86EE8F33AA1A}.Debug|ARM.Build.0 = Debug|ARM - {1C538546-0768-4071-81A6-86EE8F33AA1A}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {1C538546-0768-4071-81A6-86EE8F33AA1A}.Debug|ARM64.Build.0 = Debug|ARM64 - {1C538546-0768-4071-81A6-86EE8F33AA1A}.Debug|x64.ActiveCfg = Debug|x64 - {1C538546-0768-4071-81A6-86EE8F33AA1A}.Debug|x64.Build.0 = Debug|x64 - {1C538546-0768-4071-81A6-86EE8F33AA1A}.Debug|x86.ActiveCfg = Debug|x86 - {1C538546-0768-4071-81A6-86EE8F33AA1A}.Debug|x86.Build.0 = Debug|x86 - {1C538546-0768-4071-81A6-86EE8F33AA1A}.Release|ARM.ActiveCfg = Release|ARM - {1C538546-0768-4071-81A6-86EE8F33AA1A}.Release|ARM.Build.0 = Release|ARM - {1C538546-0768-4071-81A6-86EE8F33AA1A}.Release|ARM64.ActiveCfg = Release|ARM64 - {1C538546-0768-4071-81A6-86EE8F33AA1A}.Release|ARM64.Build.0 = Release|ARM64 - {1C538546-0768-4071-81A6-86EE8F33AA1A}.Release|x64.ActiveCfg = Release|x64 - {1C538546-0768-4071-81A6-86EE8F33AA1A}.Release|x64.Build.0 = Release|x64 - {1C538546-0768-4071-81A6-86EE8F33AA1A}.Release|x86.ActiveCfg = Release|x86 - {1C538546-0768-4071-81A6-86EE8F33AA1A}.Release|x86.Build.0 = Release|x86 - {07B432C0-5242-4EB4-982B-CA895D032AE5}.Debug|ARM.ActiveCfg = Debug|ARM - {07B432C0-5242-4EB4-982B-CA895D032AE5}.Debug|ARM.Build.0 = Debug|ARM - {07B432C0-5242-4EB4-982B-CA895D032AE5}.Debug|ARM.Deploy.0 = Debug|ARM - {07B432C0-5242-4EB4-982B-CA895D032AE5}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {07B432C0-5242-4EB4-982B-CA895D032AE5}.Debug|ARM64.Build.0 = Debug|ARM64 - {07B432C0-5242-4EB4-982B-CA895D032AE5}.Debug|ARM64.Deploy.0 = Debug|ARM64 - {07B432C0-5242-4EB4-982B-CA895D032AE5}.Debug|x64.ActiveCfg = Debug|x64 - {07B432C0-5242-4EB4-982B-CA895D032AE5}.Debug|x64.Build.0 = Debug|x64 - {07B432C0-5242-4EB4-982B-CA895D032AE5}.Debug|x64.Deploy.0 = Debug|x64 - {07B432C0-5242-4EB4-982B-CA895D032AE5}.Debug|x86.ActiveCfg = Debug|x86 - {07B432C0-5242-4EB4-982B-CA895D032AE5}.Debug|x86.Build.0 = Debug|x86 - {07B432C0-5242-4EB4-982B-CA895D032AE5}.Debug|x86.Deploy.0 = Debug|x86 - {07B432C0-5242-4EB4-982B-CA895D032AE5}.Release|ARM.ActiveCfg = Release|ARM - {07B432C0-5242-4EB4-982B-CA895D032AE5}.Release|ARM.Build.0 = Release|ARM - {07B432C0-5242-4EB4-982B-CA895D032AE5}.Release|ARM.Deploy.0 = Release|ARM - {07B432C0-5242-4EB4-982B-CA895D032AE5}.Release|ARM64.ActiveCfg = Release|ARM64 - {07B432C0-5242-4EB4-982B-CA895D032AE5}.Release|ARM64.Build.0 = Release|ARM64 - {07B432C0-5242-4EB4-982B-CA895D032AE5}.Release|ARM64.Deploy.0 = Release|ARM64 - {07B432C0-5242-4EB4-982B-CA895D032AE5}.Release|x64.ActiveCfg = Release|x64 - {07B432C0-5242-4EB4-982B-CA895D032AE5}.Release|x64.Build.0 = Release|x64 - {07B432C0-5242-4EB4-982B-CA895D032AE5}.Release|x64.Deploy.0 = Release|x64 - {07B432C0-5242-4EB4-982B-CA895D032AE5}.Release|x86.ActiveCfg = Release|x86 - {07B432C0-5242-4EB4-982B-CA895D032AE5}.Release|x86.Build.0 = Release|x86 - {07B432C0-5242-4EB4-982B-CA895D032AE5}.Release|x86.Deploy.0 = Release|x86 - {18423C3F-1E8D-4D48-829D-554EFAD2F17E}.Debug|ARM.ActiveCfg = Debug|ARM - {18423C3F-1E8D-4D48-829D-554EFAD2F17E}.Debug|ARM.Build.0 = Debug|ARM - {18423C3F-1E8D-4D48-829D-554EFAD2F17E}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {18423C3F-1E8D-4D48-829D-554EFAD2F17E}.Debug|ARM64.Build.0 = Debug|ARM64 - {18423C3F-1E8D-4D48-829D-554EFAD2F17E}.Debug|x64.ActiveCfg = Debug|x64 - {18423C3F-1E8D-4D48-829D-554EFAD2F17E}.Debug|x64.Build.0 = Debug|x64 - {18423C3F-1E8D-4D48-829D-554EFAD2F17E}.Debug|x86.ActiveCfg = Debug|x86 - {18423C3F-1E8D-4D48-829D-554EFAD2F17E}.Debug|x86.Build.0 = Debug|x86 - {18423C3F-1E8D-4D48-829D-554EFAD2F17E}.Release|ARM.ActiveCfg = Release|ARM - {18423C3F-1E8D-4D48-829D-554EFAD2F17E}.Release|ARM.Build.0 = Release|ARM - {18423C3F-1E8D-4D48-829D-554EFAD2F17E}.Release|ARM64.ActiveCfg = Release|ARM64 - {18423C3F-1E8D-4D48-829D-554EFAD2F17E}.Release|ARM64.Build.0 = Release|ARM64 - {18423C3F-1E8D-4D48-829D-554EFAD2F17E}.Release|x64.ActiveCfg = Release|x64 - {18423C3F-1E8D-4D48-829D-554EFAD2F17E}.Release|x64.Build.0 = Release|x64 - {18423C3F-1E8D-4D48-829D-554EFAD2F17E}.Release|x86.ActiveCfg = Release|x86 - {18423C3F-1E8D-4D48-829D-554EFAD2F17E}.Release|x86.Build.0 = Release|x86 - {BAB95B1F-293D-440D-B19F-95FBFA3AA6EF}.Debug|ARM.ActiveCfg = Debug|ARM - {BAB95B1F-293D-440D-B19F-95FBFA3AA6EF}.Debug|ARM.Build.0 = Debug|ARM - {BAB95B1F-293D-440D-B19F-95FBFA3AA6EF}.Debug|ARM.Deploy.0 = Debug|ARM - {BAB95B1F-293D-440D-B19F-95FBFA3AA6EF}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {BAB95B1F-293D-440D-B19F-95FBFA3AA6EF}.Debug|ARM64.Build.0 = Debug|ARM64 - {BAB95B1F-293D-440D-B19F-95FBFA3AA6EF}.Debug|ARM64.Deploy.0 = Debug|ARM64 - {BAB95B1F-293D-440D-B19F-95FBFA3AA6EF}.Debug|x64.ActiveCfg = Debug|x64 - {BAB95B1F-293D-440D-B19F-95FBFA3AA6EF}.Debug|x64.Build.0 = Debug|x64 - {BAB95B1F-293D-440D-B19F-95FBFA3AA6EF}.Debug|x64.Deploy.0 = Debug|x64 - {BAB95B1F-293D-440D-B19F-95FBFA3AA6EF}.Debug|x86.ActiveCfg = Debug|x86 - {BAB95B1F-293D-440D-B19F-95FBFA3AA6EF}.Debug|x86.Build.0 = Debug|x86 - {BAB95B1F-293D-440D-B19F-95FBFA3AA6EF}.Debug|x86.Deploy.0 = Debug|x86 - {BAB95B1F-293D-440D-B19F-95FBFA3AA6EF}.Release|ARM.ActiveCfg = Release|ARM - {BAB95B1F-293D-440D-B19F-95FBFA3AA6EF}.Release|ARM.Build.0 = Release|ARM - {BAB95B1F-293D-440D-B19F-95FBFA3AA6EF}.Release|ARM.Deploy.0 = Release|ARM - {BAB95B1F-293D-440D-B19F-95FBFA3AA6EF}.Release|ARM64.ActiveCfg = Release|ARM64 - {BAB95B1F-293D-440D-B19F-95FBFA3AA6EF}.Release|ARM64.Build.0 = Release|ARM64 - {BAB95B1F-293D-440D-B19F-95FBFA3AA6EF}.Release|ARM64.Deploy.0 = Release|ARM64 - {BAB95B1F-293D-440D-B19F-95FBFA3AA6EF}.Release|x64.ActiveCfg = Release|x64 - {BAB95B1F-293D-440D-B19F-95FBFA3AA6EF}.Release|x64.Build.0 = Release|x64 - {BAB95B1F-293D-440D-B19F-95FBFA3AA6EF}.Release|x64.Deploy.0 = Release|x64 - {BAB95B1F-293D-440D-B19F-95FBFA3AA6EF}.Release|x86.ActiveCfg = Release|x86 - {BAB95B1F-293D-440D-B19F-95FBFA3AA6EF}.Release|x86.Build.0 = Release|x86 - {BAB95B1F-293D-440D-B19F-95FBFA3AA6EF}.Release|x86.Deploy.0 = Release|x86 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {740E3731-7142-4CC6-931A-32FF8D672FCA} = {1E7F5677-399F-4C32-B47D-F6497CEC8977} - {622593A1-7B0D-4D71-8369-371601B8BEE1} = {1E7F5677-399F-4C32-B47D-F6497CEC8977} - {46AAFC56-77C9-4666-B7C0-959B9A6C3400} = {DE733C33-3FDC-4164-9FFA-65515BC9FBAB} - {1A536FCE-940C-4184-86A7-808AC521B3C3} = {DE733C33-3FDC-4164-9FFA-65515BC9FBAB} - {1C538546-0768-4071-81A6-86EE8F33AA1A} = {DA3A5B44-6038-4656-A8B9-22944BD2917D} - {07B432C0-5242-4EB4-982B-CA895D032AE5} = {DA3A5B44-6038-4656-A8B9-22944BD2917D} - {18423C3F-1E8D-4D48-829D-554EFAD2F17E} = {8E46E97F-B3AB-45B1-9C90-876A8D7C7DB6} - {BAB95B1F-293D-440D-B19F-95FBFA3AA6EF} = {8E46E97F-B3AB-45B1-9C90-876A8D7C7DB6} - EndGlobalSection -EndGlobal diff --git a/computeparticles/computeparticles.cpp b/computeparticles/computeparticles.cpp index 176edd6e..1b3c35f5 100644 --- a/computeparticles/computeparticles.cpp +++ b/computeparticles/computeparticles.cpp @@ -110,7 +110,7 @@ public: void loadTextures() { textureLoader->loadTexture( - "./../data/textures/particle01_rgba.ktx", + getAssetPath() + "textures/particle01_rgba.ktx", VK_FORMAT_R8G8B8A8_UNORM, &textureColorMap, false); @@ -530,8 +530,8 @@ public: // Load shaders std::array shaderStages; - shaderStages[0] = loadShader("./../data/shaders/computeparticles/particle.vert.spv", VK_SHADER_STAGE_VERTEX_BIT); - shaderStages[1] = loadShader("./../data/shaders/computeparticles/particle.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT); + shaderStages[0] = loadShader(getAssetPath() + "shaders/computeparticles/particle.vert.spv", VK_SHADER_STAGE_VERTEX_BIT); + shaderStages[1] = loadShader(getAssetPath() + "shaders/computeparticles/particle.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT); VkGraphicsPipelineCreateInfo pipelineCreateInfo = vkTools::initializers::pipelineCreateInfo( @@ -641,7 +641,7 @@ public: vkTools::initializers::computePipelineCreateInfo( computePipelineLayout, 0); - computePipelineCreateInfo.stage = loadShader("./../data/shaders/computeparticles/particle.comp.spv", VK_SHADER_STAGE_COMPUTE_BIT); + computePipelineCreateInfo.stage = loadShader(getAssetPath() + "shaders/computeparticles/particle.comp.spv", VK_SHADER_STAGE_COMPUTE_BIT); err = vkCreateComputePipelines(device, pipelineCache, 1, &computePipelineCreateInfo, nullptr, &pipelines.compute); assert(!err); } @@ -746,8 +746,7 @@ public: VulkanExample *vulkanExample; -#ifdef _WIN32 - +#if defined(_WIN32) LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { if (vulkanExample != NULL) @@ -765,9 +764,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) } return (DefWindowProc(hWnd, uMsg, wParam, lParam)); } - -#else - +#elif defined(__linux__) && !defined(__ANDROID__) static void handleEvent(const xcb_generic_event_t *event) { if (vulkanExample != NULL) @@ -777,21 +774,42 @@ static void handleEvent(const xcb_generic_event_t *event) } #endif -#ifdef _WIN32 +// Main entry point +#if defined(_WIN32) +// Windows entry point int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR pCmdLine, int nCmdShow) -#else +#elif defined(__ANDROID__) +// Android entry point +void android_main(android_app* state) +#elif defined(__linux__) +// Linux entry point int main(const int argc, const char *argv[]) #endif { +#if defined(__ANDROID__) + // Removing this may cause the compiler to omit the main entry point + // which would make the application crash at start + app_dummy(); +#endif vulkanExample = new VulkanExample(); -#ifdef _WIN32 +#if defined(_WIN32) vulkanExample->setupWindow(hInstance, WndProc); -#else +#elif defined(__ANDROID__) + // Attach vulkan example to global android application state + state->userData = vulkanExample; + state->onAppCmd = VulkanExample::handleAppCommand; + state->onInputEvent = VulkanExample::handleAppInput; + vulkanExample->androidApp = state; +#elif defined(__linux__) vulkanExample->setupWindow(); #endif +#if !defined(__ANDROID__) vulkanExample->initSwapchain(); vulkanExample->prepare(); +#endif vulkanExample->renderLoop(); +#if !defined(__ANDROID__) delete(vulkanExample); return 0; -} +#endif +} \ No newline at end of file