diff --git a/CMakeLists.txt b/CMakeLists.txt index 6a09f59..a3a7bfe 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,11 +4,11 @@ project(Informatikprojekt C) set(CMAKE_C_STANDARD 11) set(PROJECT_SOURCES particlesystem.h particlesystem.c utils.h utils.c) set(PROJECT_SOURCES_OPENGL ${PROJECT_SOURCES} initOpenGL.h initOpenGL.c utils.h glad/src/glad.c) -set(PROJECT_SOURCES_VULKAN ${PROJECT_SOURCES} newVulkan/initVulkan.h newVulkan/initVulkan.c) +set(PROJECT_SOURCES_VULKAN ${PROJECT_SOURCES} initVulkan.h initVulkan.c) add_executable(Informatikprojekt cpuMain.c ${PROJECT_SOURCES_OPENGL}) add_executable(Informatikprojekt_OpenGL openglMain.c ${PROJECT_SOURCES_OPENGL}) -add_executable(Informatikprojekt_Vulkan newVulkan/vulkanMain.c ${PROJECT_SOURCES_VULKAN}) +add_executable(Informatikprojekt_Vulkan vulkanMain.c ${PROJECT_SOURCES_VULKAN}) # Copy shader file to output directory ## OpenGL diff --git a/initVulkan.c b/initVulkan.c index 5b3afa1..0ee5c5f 100644 --- a/initVulkan.c +++ b/initVulkan.c @@ -1,393 +1,5 @@ #include "initVulkan.h" - -int initVulkan(VkInstance *vkInstance, VkDevice *device, VkSurfaceKHR *surface, GLFWwindow *window, - VkSwapchainKHR *swapChain, VkImageView **imageViews, uint32_t *amountImages) -{ - // VkApplicationInfo - VkApplicationInfo appInfo; - createAppInfo(&appInfo); - - // VkInstanceCreateInfo - uint32_t amountOfLayers; - vkEnumerateInstanceLayerProperties(&amountOfLayers, NULL); - VkLayerProperties layers[amountOfLayers]; - vkEnumerateInstanceLayerProperties(&amountOfLayers, layers); - - VkInstanceCreateInfo instanceInfo; - createInstanceInfo(&appInfo, &instanceInfo); - - // Vulkan Instance - ASSERT_VK_SUCCESS(vkCreateInstance(&instanceInfo, NULL, vkInstance)) - - // Get physical device - uint32_t amountOfPhysicalDevices = 0; - ASSERT_VK_SUCCESS(vkEnumeratePhysicalDevices(*vkInstance, &amountOfPhysicalDevices, NULL)) // Let fill amount first automatically - VkPhysicalDevice physicalDevices[amountOfPhysicalDevices]; // create array for physical devices - ASSERT_VK_SUCCESS(vkEnumeratePhysicalDevices(*vkInstance, &amountOfPhysicalDevices, physicalDevices)) // Call again with array - - // Create Window Surface - ASSERT_VK_SUCCESS(glfwCreateWindowSurface(*vkInstance, window, NULL, surface)) - - printStats(&physicalDevices[0], surface); - - // Queue info - VkDeviceQueueCreateInfo queueInfo; - createQueueInfo(&queueInfo); - - // Device info - VkPhysicalDeviceFeatures usedFeatures = {}; - VkDeviceCreateInfo deviceInfo; - createDeviceInfo(&queueInfo, &deviceInfo, &usedFeatures); - - // Logical device - ASSERT_VK_SUCCESS(vkCreateDevice(physicalDevices[0], &deviceInfo, NULL, device)) - - // Queue - VkQueue queue; - vkGetDeviceQueue(*device, 0, 0, &queue); - - // Swap chain support - VkBool32 swapChainSupport; - ASSERT_VK_SUCCESS(vkGetPhysicalDeviceSurfaceSupportKHR(physicalDevices[0], 0, *surface, &swapChainSupport)) - if (!swapChainSupport) - { - printf("Swap chain not supported!"); - return FAILURE; - } - - // Swap chain info - VkSwapchainCreateInfoKHR swapChainCreateInfo; - createSwapChainInfo(&swapChainCreateInfo, surface); - - // Swap chain - ASSERT_VK_SUCCESS(vkCreateSwapchainKHR(*device, &swapChainCreateInfo, NULL, swapChain)) - - // Swap chain images - vkGetSwapchainImagesKHR(*device, *swapChain, amountImages, NULL); - VkImage swapChainImages[*amountImages]; - ASSERT_VK_SUCCESS(vkGetSwapchainImagesKHR(*device, *swapChain, amountImages, swapChainImages)) - - // Image view - *imageViews = malloc(*amountImages * sizeof(VkImageView)); - VkImageViewCreateInfo imageViewInfo; - for (int i = 0; i < *amountImages; i++) - { - createImageViewInfo(&imageViewInfo, swapChainImages, i); - ASSERT_VK_SUCCESS(vkCreateImageView(*device, &imageViewInfo, NULL, &*imageViews[i])) - } - - return SUCCESS; -} - -void createAppInfo(VkApplicationInfo *appInfo) -{ - appInfo->sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; - appInfo->pNext = NULL; - appInfo->pApplicationName = APP_NAME; - appInfo->applicationVersion = APP_VERSION; - appInfo->pEngineName = ENGINE_NAME; - appInfo->engineVersion = ENGINE_VERSION; - appInfo->apiVersion = VK_API_VERSION_1_1; -} - -void createInstanceInfo(VkApplicationInfo *appInfo, VkInstanceCreateInfo *instanceInfo) -{ - GLuint amountOfGLFWExtensions; - const char **glfwExtensions = glfwGetRequiredInstanceExtensions(&amountOfGLFWExtensions); - - instanceInfo->sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; - instanceInfo->pNext = NULL; - instanceInfo->flags = 0; - instanceInfo->pApplicationInfo = appInfo; - instanceInfo->enabledLayerCount = 0; - instanceInfo->ppEnabledLayerNames = NULL; - instanceInfo->enabledExtensionCount = amountOfGLFWExtensions; - instanceInfo->ppEnabledExtensionNames = glfwExtensions; -} - -void createQueueInfo(VkDeviceQueueCreateInfo *queueInfo) -{ - queueInfo->sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; - queueInfo->pNext = NULL; - queueInfo->flags = 0; - queueInfo->queueFamilyIndex = 0; - queueInfo->queueCount = 1; - queueInfo->pQueuePriorities = NULL; -} - -void createDeviceInfo(VkDeviceQueueCreateInfo *queueInfo, VkDeviceCreateInfo *deviceInfo, VkPhysicalDeviceFeatures *features) -{ - const char *deviceExtensions[1] = { VK_KHR_SWAPCHAIN_EXTENSION_NAME }; - - deviceInfo->sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; - deviceInfo->pNext = NULL; - deviceInfo->flags = 0; - deviceInfo->queueCreateInfoCount = 1; - deviceInfo->pQueueCreateInfos = queueInfo; - deviceInfo->enabledLayerCount = 0; - deviceInfo->ppEnabledLayerNames = NULL; - deviceInfo->enabledExtensionCount = 1; - deviceInfo->ppEnabledExtensionNames = deviceExtensions; - deviceInfo->pEnabledFeatures = features; -} - -void createSwapChainInfo(VkSwapchainCreateInfoKHR *swapChainCreateInfo, VkSurfaceKHR *surface) -{ - VkExtent2D imageExtent = { WIDTH, HEIGHT }; - - swapChainCreateInfo->sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR; - swapChainCreateInfo->pNext = NULL; - swapChainCreateInfo->flags = 0; - swapChainCreateInfo->surface = *surface; - swapChainCreateInfo->minImageCount = 1; - swapChainCreateInfo->imageFormat = VK_FORMAT_B8G8R8A8_UNORM; - swapChainCreateInfo->imageColorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR; - swapChainCreateInfo->imageExtent = imageExtent; - swapChainCreateInfo->imageArrayLayers = 1; - swapChainCreateInfo->imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; - swapChainCreateInfo->imageSharingMode = VK_SHARING_MODE_EXCLUSIVE; - swapChainCreateInfo->queueFamilyIndexCount = 0; - swapChainCreateInfo->pQueueFamilyIndices = NULL; - swapChainCreateInfo->preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR; - swapChainCreateInfo->compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; - swapChainCreateInfo->presentMode = VK_PRESENT_MODE_FIFO_KHR; - swapChainCreateInfo->clipped = VK_FALSE; - swapChainCreateInfo->oldSwapchain = VK_NULL_HANDLE; -} - -void createImageViewInfo(VkImageViewCreateInfo *imageViewInfo, VkImage *swapChainImages, int index) -{ - VkComponentMapping componentMapping = { - VK_COMPONENT_SWIZZLE_IDENTITY, - VK_COMPONENT_SWIZZLE_IDENTITY, - VK_COMPONENT_SWIZZLE_IDENTITY, - VK_COMPONENT_SWIZZLE_IDENTITY - }; - VkImageSubresourceRange subresourceRange = { - VK_IMAGE_ASPECT_COLOR_BIT,0, 1, 0, 1 - }; - - imageViewInfo->sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; - imageViewInfo->pNext = NULL; - imageViewInfo->flags = 0; - imageViewInfo->image = swapChainImages[index]; - imageViewInfo->viewType = VK_IMAGE_VIEW_TYPE_2D; - imageViewInfo->format = VK_FORMAT_B8G8R8A8_UNORM; - imageViewInfo->components = componentMapping; - imageViewInfo->subresourceRange = subresourceRange; -} - -void createSemaphoreInfo(VkSemaphoreCreateInfo *semaphoreInfo) -{ - semaphoreInfo->sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO; - semaphoreInfo->pNext = NULL; - semaphoreInfo->flags = 0; -} - -void createAttachmentDescription(VkAttachmentDescription *attachmentDescription) -{ - attachmentDescription->flags = 0; - attachmentDescription->format = VK_FORMAT_B8G8R8A8_UNORM; - attachmentDescription->samples = VK_SAMPLE_COUNT_1_BIT; - attachmentDescription->loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - attachmentDescription->storeOp = VK_ATTACHMENT_STORE_OP_STORE; - attachmentDescription->stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - attachmentDescription->stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; - attachmentDescription->initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; - attachmentDescription->finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; -} - -void createAttachmentReference(VkAttachmentReference *attachmentReference, uint32_t attachment) -{ - attachmentReference->attachment = attachment; - attachmentReference->layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; -} - -void createSubpassDescription(VkSubpassDescription *subpassDescription, VkPipelineBindPoint bindPoint, - VkAttachmentReference *attachmentReference) -{ - subpassDescription->flags = 0; - subpassDescription->pipelineBindPoint = bindPoint; - subpassDescription->inputAttachmentCount = 0; - subpassDescription->pInputAttachments = NULL; - subpassDescription->colorAttachmentCount = 1; - subpassDescription->pColorAttachments = attachmentReference; - subpassDescription->pResolveAttachments = NULL; - subpassDescription->pDepthStencilAttachment = NULL; - subpassDescription->preserveAttachmentCount = 0; - subpassDescription->pPreserveAttachments = NULL; -} - -void createRenderPassInfo(VkRenderPassCreateInfo *renderPassInfo, VkAttachmentDescription *attachmentDescriptions, VkSubpassDescription *subpassDescriptions) -{ - renderPassInfo->sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; - renderPassInfo->pNext = NULL; - renderPassInfo->flags = 0; - renderPassInfo->attachmentCount = 1; - renderPassInfo->pAttachments = attachmentDescriptions; - renderPassInfo->subpassCount = 1; - renderPassInfo->pSubpasses = subpassDescriptions; - renderPassInfo->dependencyCount = 0; - renderPassInfo->pDependencies = NULL; -} - -void createGraphicsPipelineInfo(VkGraphicsPipelineCreateInfo *graphicsPipelineInfo, - VkPipelineShaderStageCreateInfo *shaderStages, - VkPipelineVertexInputStateCreateInfo *vertexInputState, - VkPipelineInputAssemblyStateCreateInfo *inputAssemblyState, - VkPipelineViewportStateCreateInfo *viewportState, - VkPipelineRasterizationStateCreateInfo *rasterizationState, - VkPipelineMultisampleStateCreateInfo *multisampleState, - VkPipelineColorBlendStateCreateInfo *colorBlendState, VkPipelineLayout *pipelineLayout, - VkRenderPass *renderPass) -{ - graphicsPipelineInfo->sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; - graphicsPipelineInfo->pNext = NULL; - graphicsPipelineInfo->flags = 0; - graphicsPipelineInfo->stageCount = 3; - graphicsPipelineInfo->pStages = shaderStages; - graphicsPipelineInfo->pVertexInputState = vertexInputState; - graphicsPipelineInfo->pInputAssemblyState = inputAssemblyState; - graphicsPipelineInfo->pTessellationState = NULL; - graphicsPipelineInfo->pViewportState = viewportState; - graphicsPipelineInfo->pRasterizationState = rasterizationState; - graphicsPipelineInfo->pMultisampleState = multisampleState; - graphicsPipelineInfo->pDepthStencilState = NULL; - graphicsPipelineInfo->pColorBlendState = colorBlendState; - graphicsPipelineInfo->pDynamicState = NULL; - graphicsPipelineInfo->layout = *pipelineLayout; - graphicsPipelineInfo->renderPass = *renderPass; - graphicsPipelineInfo->subpass = 0; - graphicsPipelineInfo->basePipelineHandle = VK_NULL_HANDLE; - graphicsPipelineInfo->basePipelineIndex = -1; -} - -void createFramebufferInfo(VkFramebufferCreateInfo *framebufferInfo, VkRenderPass *renderPass, VkImageView *imageView) -{ - framebufferInfo->sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; - framebufferInfo->pNext = NULL; - framebufferInfo->flags = 0; - framebufferInfo->renderPass = *renderPass; - framebufferInfo->attachmentCount = 1; - framebufferInfo->pAttachments = imageView; - framebufferInfo->width = WIDTH; - framebufferInfo->height = HEIGHT; - framebufferInfo->layers = 1; -} - -void createCommandPoolInfo(VkCommandPoolCreateInfo *commandPoolInfo, uint32_t queueFamilyIndex) -{ - commandPoolInfo->sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; - commandPoolInfo->pNext = NULL; - commandPoolInfo->flags = 0; - commandPoolInfo->queueFamilyIndex = queueFamilyIndex; -} - -void createCommandBufferAllocateInfo(VkCommandBufferAllocateInfo *commandBufferAllocateInfo, VkCommandPool *commandPool, uint32_t amountImages) -{ - commandBufferAllocateInfo->sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; - commandBufferAllocateInfo->pNext = NULL; - commandBufferAllocateInfo->commandPool = *commandPool; - commandBufferAllocateInfo->level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; - commandBufferAllocateInfo->commandBufferCount = amountImages; -} - -void createCommandBufferBeginInfo(VkCommandBufferBeginInfo *commandBufferBeginInfo) -{ - commandBufferBeginInfo->sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; - commandBufferBeginInfo->pNext = NULL; - commandBufferBeginInfo->flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT; - commandBufferBeginInfo->pInheritanceInfo = NULL; -} - -void createRenderPassBeginInfo(VkRenderPassBeginInfo *renderPassBeginInfo, VkRenderPass *renderPass, VkFramebuffer *framebuffer) -{ - VkRect2D renderArea = { {0, 0}, {WIDTH, HEIGHT} }; - VkClearValue clearValue = {0, 0, 0, 1}; - - renderPassBeginInfo->sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; - renderPassBeginInfo->pNext = NULL; - renderPassBeginInfo->renderPass = *renderPass; - renderPassBeginInfo->framebuffer = *framebuffer; - renderPassBeginInfo->renderArea = renderArea; - renderPassBeginInfo->clearValueCount = 1; - renderPassBeginInfo->pClearValues = &clearValue; -} - -void createBufferInfo(VkBufferCreateInfo *bufferCreateInfo, VkBufferUsageFlags usageFlags, VkDeviceSize size) -{ - bufferCreateInfo->sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; - bufferCreateInfo->pNext = NULL; - bufferCreateInfo->flags = 0; - bufferCreateInfo->size = size; - bufferCreateInfo->usage = usageFlags; - bufferCreateInfo->sharingMode = VK_SHARING_MODE_EXCLUSIVE; - bufferCreateInfo->queueFamilyIndexCount = 0; - bufferCreateInfo->pQueueFamilyIndices = NULL; -} - -void createMemoryAllocateInfo(VkMemoryAllocateInfo *memoryAllocateInfo, VkDeviceSize size, uint32_t memoryTypeIndex) -{ - memoryAllocateInfo->sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; - memoryAllocateInfo->pNext = NULL; - memoryAllocateInfo->allocationSize = size; - memoryAllocateInfo->memoryTypeIndex = memoryTypeIndex; -} - -void shutdownVulkan(VkInstance *vkInstance, VkDevice *device, VkSurfaceKHR *surface, VkSwapchainKHR *swapChain, - VkImageView *imageViews, uint32_t imageViewsSize, VkShaderModule *modules, - uint32_t shaderModulesSize, VkPipelineLayout *pipelineLayouts, uint32_t pipelineLayoutsSize, - VkRenderPass *renderPasses, uint32_t renderPassesSize, VkPipeline *pipelines, - uint32_t pipelinesSize, VkFramebuffer *framebuffers, VkCommandPool *commandPool, - VkCommandBuffer *commandBuffers, VkSemaphore *semaphores, uint32_t semaphoresSize) -{ - vkDeviceWaitIdle(*device); - - for (int i = 0; i < semaphoresSize; ++i) - { - vkDestroySemaphore(*device, semaphores[i], NULL); - } - - vkFreeCommandBuffers(*device, *commandPool, imageViewsSize, commandBuffers); - free(commandBuffers); - - vkDestroyCommandPool(*device, *commandPool, NULL); - - for (int i = 0; i < imageViewsSize; ++i) - { - vkDestroyFramebuffer(*device, framebuffers[i], NULL); - } - - for (int i = 0; i < pipelinesSize; ++i) - { - vkDestroyPipeline(*device, pipelines[i], NULL); - } - - for (int i = 0; i < renderPassesSize; ++i) - { - vkDestroyRenderPass(*device, renderPasses[i], NULL); - } - - for (int i = 0; i < pipelineLayoutsSize; ++i) - { - vkDestroyPipelineLayout(*device, pipelineLayouts[i], NULL); - } - - for (int i = 0; i < shaderModulesSize; ++i) - { - vkDestroyShaderModule(*device, modules[i], NULL); - } - - for (int i = 0; i < imageViewsSize; i++) - { - vkDestroyImageView(*device, imageViews[i], NULL); - } - - vkDestroySwapchainKHR(*device, *swapChain, NULL); - vkDestroySurfaceKHR(*vkInstance, *surface, NULL); - vkDestroyDevice(*device, NULL); - vkDestroyInstance(*vkInstance, NULL); -} +#include void shutdownGLFW(GLFWwindow *window) { @@ -395,228 +7,890 @@ void shutdownGLFW(GLFWwindow *window) glfwTerminate(); } -int createShaderModule(VkDevice device, VkShaderModule *shaderModule, const char *shaderSource, long sourceSize) +void createInstance(Compute *compute, Graphics *graphics) { + GLuint enabledLayerSize = 0; + const char **enabledLayer; + GLuint extensionsSize; + const char **glfwExtensions = glfwGetRequiredInstanceExtensions(&extensionsSize); + + #ifndef NDEBUG + enabledLayerSize = 1; + enabledLayer = malloc(sizeof(char *)); + enabledLayer[0] = "VK_LAYER_LUNARG_standard_validation"; + #endif + + VkApplicationInfo applicationInfo = {}; + applicationInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; + applicationInfo.pApplicationName = APP_NAME; + applicationInfo.applicationVersion = APP_VERSION; + applicationInfo.pEngineName = ENGINE_NAME; + applicationInfo.engineVersion = ENGINE_VERSION; + applicationInfo.apiVersion = VK_API_VERSION_1_2; + + VkInstanceCreateInfo instanceCreateInfo = {}; + instanceCreateInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; + instanceCreateInfo.flags = 0; + instanceCreateInfo.pApplicationInfo = &applicationInfo; + instanceCreateInfo.enabledLayerCount = enabledLayerSize; + instanceCreateInfo.ppEnabledLayerNames = enabledLayer; + instanceCreateInfo.enabledExtensionCount = extensionsSize; + instanceCreateInfo.ppEnabledExtensionNames = glfwExtensions; + + ASSERT_VK(vkCreateInstance(&instanceCreateInfo, NULL, &(compute->instance))) + + graphics->instance = compute->instance; +} + +void findPhysicalDevice(Compute *compute, Graphics *graphics) +{ + uint32_t devicesSize; + vkEnumeratePhysicalDevices(compute->instance, &devicesSize, NULL); + + if (devicesSize <= 0) + { + printf("Fatal : No device found with Vulkan support!"); + assert(devicesSize > 0); + } + + VkPhysicalDevice physicalDevices[devicesSize]; + vkEnumeratePhysicalDevices(compute->instance, &devicesSize, physicalDevices); + + for (int i = 0; i < devicesSize; ++i) + { + VkPhysicalDeviceProperties deviceProperties = {}; + vkGetPhysicalDeviceProperties(physicalDevices[i], &deviceProperties); + + if (WORKGROUP_SIZE_X <= deviceProperties.limits.maxComputeWorkGroupSize[0] + && PARTICLE_AMOUNT / WORKGROUP_SIZE_X <= deviceProperties.limits.maxComputeWorkGroupCount[0] + && (uint32_t) (PARTICLE_SIZE * PARTICLE_AMOUNT) <= deviceProperties.limits.maxStorageBufferRange) + { + compute->physicalDevice = physicalDevices[i]; + break; + } + } + + if (!compute->physicalDevice) + { + printf("Fatal : No device found with capable limits!"); + assert(compute->physicalDevice); + } + + graphics->physicalDevice = compute->physicalDevice; +} + +uint32_t getQueueFamilyIndex(VkPhysicalDevice physicalDevice, VkQueueFlagBits queueFlagBits, int noGraphics) +{ + uint32_t queueFamiliesSize; + vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueFamiliesSize, NULL); + VkQueueFamilyProperties queueFamilies[queueFamiliesSize]; + vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueFamiliesSize, queueFamilies); + + for (uint32_t i = 0; i < queueFamiliesSize; ++i) + { + if (noGraphics && (queueFamilies[i].queueFlags & VK_QUEUE_GRAPHICS_BIT)) + { + } + else if ((queueFamilies[i].queueFlags & queueFlagBits) == queueFlagBits) + { + return i; + } + } + + return UINT32_MAX; +} + +void createDevice(Compute *compute, Graphics *graphics) +{ + compute->queueFamilyIndex = getQueueFamilyIndex(compute->physicalDevice, VK_QUEUE_COMPUTE_BIT, 1); + if (compute->queueFamilyIndex == UINT32_MAX) + { + printf("ERROR: No Queue family found with desired capabilities!\n"); + assert( compute->queueFamilyIndex < UINT32_MAX); + } + + float queuePriority = 1.0f; + VkDeviceQueueCreateInfo computeDeviceQueueCreateInfo = {}; + computeDeviceQueueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; + computeDeviceQueueCreateInfo.queueFamilyIndex = compute->queueFamilyIndex; + computeDeviceQueueCreateInfo.queueCount = 1; + computeDeviceQueueCreateInfo.pQueuePriorities = &queuePriority; + + graphics->queueFamilyIndex = getQueueFamilyIndex(graphics->physicalDevice, VK_QUEUE_GRAPHICS_BIT, 0); + if (graphics->queueFamilyIndex == UINT32_MAX) + { + printf("ERROR: No Queue family found with desired capabilities!\n"); + assert( compute->queueFamilyIndex < UINT32_MAX); + } + + VkDeviceQueueCreateInfo graphicsDeviceQueueCreateInfo = {}; + graphicsDeviceQueueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; + graphicsDeviceQueueCreateInfo.queueFamilyIndex = graphics->queueFamilyIndex; + graphicsDeviceQueueCreateInfo.queueCount = 1; + graphicsDeviceQueueCreateInfo.pQueuePriorities = &queuePriority; + + VkDeviceQueueCreateInfo deviceQueueCreateInfos[2] = { + computeDeviceQueueCreateInfo, + graphicsDeviceQueueCreateInfo + }; + + VkPhysicalDeviceFeatures physicalDeviceFeatures = {}; + const char *swapchainExtension = VK_KHR_SWAPCHAIN_EXTENSION_NAME; + const char **extensions = &swapchainExtension; + + VkDeviceCreateInfo deviceCreateInfo = {}; + deviceCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; + deviceCreateInfo.queueCreateInfoCount = 2; + deviceCreateInfo.pQueueCreateInfos = deviceQueueCreateInfos; + deviceCreateInfo.pEnabledFeatures = &physicalDeviceFeatures; + deviceCreateInfo.enabledExtensionCount = 1; + deviceCreateInfo.ppEnabledExtensionNames = extensions; + + ASSERT_VK(vkCreateDevice(compute->physicalDevice, &deviceCreateInfo, NULL, &(compute->device))) + + graphics->device = compute->device; + + vkGetDeviceQueue(compute->device, compute->queueFamilyIndex, 0, &(compute->queue)); + vkGetDeviceQueue(graphics->device, graphics->queueFamilyIndex, 0, &(graphics->queue)); +} + +uint32_t findMemoryType(Compute *compute, uint32_t memoryTypeBits, VkMemoryPropertyFlags properties) +{ + VkPhysicalDeviceMemoryProperties memoryProperties; + vkGetPhysicalDeviceMemoryProperties(compute->physicalDevice, &memoryProperties); + + for (uint32_t i = 0; i < memoryProperties.memoryTypeCount; i++) + { + if ((memoryTypeBits & (1u << i)) + && ((memoryProperties.memoryTypes[i].propertyFlags & properties) == properties)) + return i; + } + + return UINT32_MAX; +} + +void createParticleBuffer(Compute *compute, Graphics *graphics) +{ + uint32_t queueFamilyIndices[2] = { + compute->queueFamilyIndex, + graphics->queueFamilyIndex + }; + + VkBufferCreateInfo particleBufferCreateInfo = {}; + particleBufferCreateInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; + particleBufferCreateInfo.size = compute->particleBufferSize; + particleBufferCreateInfo.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; + particleBufferCreateInfo.sharingMode = VK_SHARING_MODE_CONCURRENT; + particleBufferCreateInfo.queueFamilyIndexCount = 2; + particleBufferCreateInfo.pQueueFamilyIndices = queueFamilyIndices; + + ASSERT_VK(vkCreateBuffer(compute->device, &particleBufferCreateInfo, NULL, &(compute->particleBuffer))) + + VkMemoryRequirements particleBufferMemoryRequirements; + vkGetBufferMemoryRequirements(compute->device, compute->particleBuffer, &particleBufferMemoryRequirements); + + VkMemoryAllocateInfo particleMemoryAllocateInfo = {}; + particleMemoryAllocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; + particleMemoryAllocateInfo.allocationSize = particleBufferMemoryRequirements.size; + particleMemoryAllocateInfo.memoryTypeIndex = findMemoryType(compute, + particleBufferMemoryRequirements.memoryTypeBits, + VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + + ASSERT_VK(vkAllocateMemory(compute->device, &particleMemoryAllocateInfo, NULL, &(compute->particleBufferMemory))) + + ASSERT_VK(vkBindBufferMemory(compute->device, compute->particleBuffer, compute->particleBufferMemory, 0)) +} + +void createComputeBuffer(Compute *compute, uint32_t bufferSize, VkBufferUsageFlags usageFlags, VkBuffer *buffer, + VkDeviceMemory *bufferMemory, VkMemoryPropertyFlags memoryPropertyFlags) +{ + VkBufferCreateInfo bufferCreateInfo = {}; + bufferCreateInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; + bufferCreateInfo.size = bufferSize; + bufferCreateInfo.usage = usageFlags; + bufferCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; + + ASSERT_VK(vkCreateBuffer(compute->device, &bufferCreateInfo, NULL, buffer)) + + VkMemoryRequirements bufferMemoryRequirements; + vkGetBufferMemoryRequirements(compute->device, *buffer, &bufferMemoryRequirements); + + VkMemoryAllocateInfo memoryAllocateInfo = {}; + memoryAllocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; + memoryAllocateInfo.allocationSize = bufferMemoryRequirements.size; + memoryAllocateInfo.memoryTypeIndex = findMemoryType(compute, + bufferMemoryRequirements.memoryTypeBits, + memoryPropertyFlags); + + ASSERT_VK(vkAllocateMemory(compute->device, &memoryAllocateInfo, NULL, bufferMemory)) + + ASSERT_VK(vkBindBufferMemory(compute->device, *buffer, *bufferMemory, 0)) +} + +void createComputeBuffers(Compute *compute) +{ + // dt Uniform Buffer + createComputeBuffer(compute, compute->dtUniformBufferSize, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, + &(compute->dtUniformBuffer), + &(compute->dtUniformBufferMemory), + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); + + // staticIn Uniform Buffer + createComputeBuffer(compute, compute->staticInUniformBufferSize, + VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, + &(compute->staticInUniformBuffer), + &(compute->staticInUniformBufferMemory), VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + +} + +void createComputeDescriptorSetLayout(Compute *compute, VkDescriptorType descriptorType, VkDescriptorSetLayout *descriptorSetLayout) +{ + VkDescriptorSetLayoutBinding descriptorSetLayoutBinding = {}; + descriptorSetLayoutBinding.binding = 0; + descriptorSetLayoutBinding.descriptorType = descriptorType; + descriptorSetLayoutBinding.descriptorCount = 1; + descriptorSetLayoutBinding.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT; + + VkDescriptorSetLayoutCreateInfo descriptorSetLayoutCreateInfo = {}; + descriptorSetLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; + descriptorSetLayoutCreateInfo.bindingCount = 1; + descriptorSetLayoutCreateInfo.pBindings = &descriptorSetLayoutBinding; + + ASSERT_VK(vkCreateDescriptorSetLayout(compute->device, &descriptorSetLayoutCreateInfo, NULL, descriptorSetLayout)) +} + +void createComputeDescriptorSetLayouts(Compute *compute) +{ + // Particle Buffer + createComputeDescriptorSetLayout(compute, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, + &(compute->particleBufferDescriptorSetLayout)); + + // dt Uniform Buffer + createComputeDescriptorSetLayout(compute, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, + &(compute->dtUniformBufferDescriptorSetLayout)); + + // staticIn Uniform Buffer + createComputeDescriptorSetLayout(compute, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, + &(compute->staticInUniformBufferDescriptorSetLayout)); +} + +void createComputeDescriptorSet(Compute *compute, VkDescriptorType descriptorType, VkDescriptorPool *descriptorPool, + VkDescriptorSetLayout *descriptorSetLayout, VkDescriptorSet *descriptorSet, + VkBuffer buffer, uint32_t bufferSize) +{ + VkDescriptorPoolSize descriptorPoolSize = {}; + descriptorPoolSize.type = descriptorType; + descriptorPoolSize.descriptorCount = 1; + + VkDescriptorPoolCreateInfo descriptorPoolCreateInfo = {}; + descriptorPoolCreateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; + descriptorPoolCreateInfo.maxSets = 1; + descriptorPoolCreateInfo.poolSizeCount = 1; + descriptorPoolCreateInfo.pPoolSizes = &descriptorPoolSize; + + ASSERT_VK(vkCreateDescriptorPool(compute->device, &descriptorPoolCreateInfo, NULL, descriptorPool)) + + VkDescriptorSetAllocateInfo descriptorSetAllocateInfo = {}; + descriptorSetAllocateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; + descriptorSetAllocateInfo.descriptorPool = *descriptorPool; + descriptorSetAllocateInfo.descriptorSetCount = 1; + descriptorSetAllocateInfo.pSetLayouts = descriptorSetLayout; + + ASSERT_VK(vkAllocateDescriptorSets(compute->device, &descriptorSetAllocateInfo, descriptorSet)) + + VkDescriptorBufferInfo descriptorBufferInfo = {}; + descriptorBufferInfo.buffer = buffer; + descriptorBufferInfo.offset = 0; + descriptorBufferInfo.range = bufferSize; + + VkWriteDescriptorSet writeDescriptorSet = {}; + writeDescriptorSet.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + writeDescriptorSet.dstSet = *descriptorSet; + writeDescriptorSet.dstBinding = 0; + writeDescriptorSet.descriptorCount = 1; + writeDescriptorSet.descriptorType = descriptorType; + writeDescriptorSet.pBufferInfo = &descriptorBufferInfo; + + vkUpdateDescriptorSets(compute->device, 1, &writeDescriptorSet, 0, NULL); +} + +void createComputeDescriptorSets(Compute *compute) +{ + // Particle Buffer + createComputeDescriptorSet(compute, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &(compute->particleBufferDescriptorPool), + &(compute->particleBufferDescriptorSetLayout), &(compute->particleBufferDescriptorSet), + compute->particleBuffer, compute->particleBufferSize); + + // dt Uniform Buffer + createComputeDescriptorSet(compute, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, &(compute->dtUniformBufferDescriptorPool), + &(compute->dtUniformBufferDescriptorSetLayout), &(compute->dtUniformBufferDescriptorSet), + compute->dtUniformBuffer, compute->dtUniformBufferSize); + + // staticIn Uniform Buffer + createComputeDescriptorSet(compute, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, + &(compute->staticInUniformBufferDescriptorPool), + &(compute->staticInUniformBufferDescriptorSetLayout), + &(compute->staticInUniformBufferDescriptorSet), + compute->staticInUniformBuffer, compute->staticInUniformBufferSize); +} + +void createShaderModule(VkDevice device, char *filename, VkShaderModule *shaderModule) +{ + long shaderSourceSize; + char *shaderSource = readFile(filename, "rb", &shaderSourceSize); + VkShaderModuleCreateInfo shaderModuleInfo; shaderModuleInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; shaderModuleInfo.pNext = NULL; shaderModuleInfo.flags = 0; - shaderModuleInfo.codeSize = sourceSize; + shaderModuleInfo.codeSize = shaderSourceSize; shaderModuleInfo.pCode = (uint32_t *) shaderSource; - ASSERT_VK_SUCCESS(vkCreateShaderModule(device, &shaderModuleInfo, NULL, shaderModule)) + ASSERT_VK(vkCreateShaderModule(device, &shaderModuleInfo, NULL, shaderModule)) - return SUCCESS; + free(shaderSource); } -void createShaderStageInfo(VkPipelineShaderStageCreateInfo *shaderStageInfo, VkShaderStageFlagBits shaderStageBit, VkShaderModule shaderModule, const char *entryPointName) +void createComputePipeline(Compute *compute) { - shaderStageInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; - shaderStageInfo->pNext = NULL; - shaderStageInfo->flags = 0; - shaderStageInfo->stage = shaderStageBit; - shaderStageInfo->module = shaderModule; - shaderStageInfo->pName = entryPointName; - shaderStageInfo->pSpecializationInfo = NULL; + createShaderModule(compute->device, "./vulkan/comp.spv", &(compute->shaderModule)); + + VkPipelineShaderStageCreateInfo pipelineShaderStageCreateInfo = {}; + pipelineShaderStageCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + pipelineShaderStageCreateInfo.stage = VK_SHADER_STAGE_COMPUTE_BIT; + pipelineShaderStageCreateInfo.module = compute->shaderModule; + pipelineShaderStageCreateInfo.pName = "main"; + + VkDescriptorSetLayout descriptorSetLayouts[] = { + compute->particleBufferDescriptorSetLayout, + compute->dtUniformBufferDescriptorSetLayout, + compute->staticInUniformBufferDescriptorSetLayout + }; + + VkPushConstantRange dtPushConstantRange = {}; + dtPushConstantRange.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT; + dtPushConstantRange.offset = 0; + dtPushConstantRange.size = sizeof(Dt); + + VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo = {}; + pipelineLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; + pipelineLayoutCreateInfo.setLayoutCount = 3; + pipelineLayoutCreateInfo.pSetLayouts = descriptorSetLayouts; + pipelineLayoutCreateInfo.pushConstantRangeCount = 1; + pipelineLayoutCreateInfo.pPushConstantRanges = &dtPushConstantRange; + + ASSERT_VK(vkCreatePipelineLayout(compute->device, &pipelineLayoutCreateInfo, NULL, &(compute->pipelineLayout))) + + VkComputePipelineCreateInfo pipelineCreateInfo = {}; + pipelineCreateInfo.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO; + pipelineCreateInfo.stage = pipelineShaderStageCreateInfo; + pipelineCreateInfo.layout = compute->pipelineLayout; + pipelineCreateInfo.basePipelineHandle = VK_NULL_HANDLE; + pipelineCreateInfo.basePipelineIndex = -1; + + ASSERT_VK(vkCreateComputePipelines(compute->device, VK_NULL_HANDLE, 1, &pipelineCreateInfo, NULL, &(compute->pipeline))) } -void createPipelineVertexInputStateInfo(VkPipelineVertexInputStateCreateInfo *vertexInputStateInfo, VkVertexInputAttributeDescription *attributes, uint32_t atrributesSize) +void mapBufferMemory(Compute *compute, VkDeviceMemory memory, void *inputData, uint32_t dataSize) { - vertexInputStateInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; - vertexInputStateInfo->pNext = NULL; - vertexInputStateInfo->flags = 0; - vertexInputStateInfo->vertexBindingDescriptionCount = 0; - vertexInputStateInfo->pVertexBindingDescriptions = NULL; - vertexInputStateInfo->vertexAttributeDescriptionCount = atrributesSize; - vertexInputStateInfo->pVertexAttributeDescriptions = attributes; + void *vkData; + vkMapMemory(compute->device, memory, 0, dataSize, 0, &vkData); + memcpy(vkData, inputData, dataSize); + vkUnmapMemory(compute->device, memory); } -void createInputAssemblyStateInfo(VkPipelineInputAssemblyStateCreateInfo *inputAssemblyStateInfo, VkPrimitiveTopology topology) +void copyBuffer(Compute *compute, VkBuffer src, VkBuffer dst, VkDeviceSize size) { - inputAssemblyStateInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; - inputAssemblyStateInfo->pNext = NULL; - inputAssemblyStateInfo->flags = 0; - inputAssemblyStateInfo->topology = topology; - inputAssemblyStateInfo->primitiveRestartEnable = VK_FALSE; + uint32_t queueFamilyIndex = getQueueFamilyIndex(compute->physicalDevice, VK_QUEUE_TRANSFER_BIT, 0); + + VkCommandPoolCreateInfo commandPoolCreateInfo = {}; + commandPoolCreateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; + commandPoolCreateInfo.flags = 0; + commandPoolCreateInfo.queueFamilyIndex = queueFamilyIndex; + + VkCommandPool stagingCommandPool; + ASSERT_VK(vkCreateCommandPool(compute->device, &commandPoolCreateInfo, NULL, &stagingCommandPool)) + + VkCommandBufferAllocateInfo allocInfo = {}; + allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; + allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; + allocInfo.commandPool = stagingCommandPool; + allocInfo.commandBufferCount = 1; + + VkCommandBuffer stagingCommandBuffer; + ASSERT_VK(vkAllocateCommandBuffers(compute->device, &allocInfo, &stagingCommandBuffer)) + + VkCommandBufferBeginInfo beginInfo = {}; + beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; + beginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; + + ASSERT_VK(vkBeginCommandBuffer(stagingCommandBuffer, &beginInfo)) + + VkBufferCopy copyRegion = { .size = size }; + vkCmdCopyBuffer(stagingCommandBuffer, src, dst, 1, ©Region); + + ASSERT_VK(vkEndCommandBuffer(stagingCommandBuffer)) + + VkSubmitInfo submitInfo = {}; + submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; + submitInfo.commandBufferCount = 1; + submitInfo.pCommandBuffers = &stagingCommandBuffer; + + VkQueue stagingQueue; + vkGetDeviceQueue(compute->device, queueFamilyIndex, 0, &stagingQueue); + + vkQueueSubmit(stagingQueue, 1, &submitInfo, VK_NULL_HANDLE); + vkQueueWaitIdle(stagingQueue); + + vkFreeCommandBuffers(compute->device, stagingCommandPool, 1, &stagingCommandBuffer); } -void createViewportStateInfo(VkPipelineViewportStateCreateInfo *viewportStateInfo, float width, float height) +void fillComputeBuffer(Compute *compute, VkBuffer dst, void *data, uint32_t dataSize) { - VkViewport viewport; + VkBuffer stagingBuffer; + VkDeviceMemory stagingBuggerMemory; + createComputeBuffer(compute, compute->particleBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, &stagingBuffer, &stagingBuggerMemory, + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); + + mapBufferMemory(compute, stagingBuggerMemory, data, dataSize); + + copyBuffer(compute, stagingBuffer, dst, dataSize); +} + +void fillComputeBuffers(Compute *compute, float *particles, Dt *dtData, StaticIn *staticInData) +{ + // Particle Buffer + fillComputeBuffer(compute, compute->particleBuffer, particles, compute->particleBufferSize); + + // dt Buffer + mapBufferMemory(compute, compute->dtUniformBufferMemory, dtData, compute->dtUniformBufferSize); + + // staticIn Buffer + fillComputeBuffer(compute, compute->staticInUniformBuffer, staticInData, compute->staticInUniformBufferSize); +} + +void createComputeCommandBuffer(Compute *compute) +{ + VkCommandPoolCreateInfo commandPoolCreateInfo = {}; + commandPoolCreateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; + commandPoolCreateInfo.flags = 0; + commandPoolCreateInfo.queueFamilyIndex = compute->queueFamilyIndex; + + ASSERT_VK(vkCreateCommandPool(compute->device, &commandPoolCreateInfo, NULL, &(compute->commandPool))) + + VkCommandBufferAllocateInfo commandBufferAllocateInfo = {}; + commandBufferAllocateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; + commandBufferAllocateInfo.commandPool = compute->commandPool; + commandBufferAllocateInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; + commandBufferAllocateInfo.commandBufferCount = 1; + + ASSERT_VK(vkAllocateCommandBuffers(compute->device, &commandBufferAllocateInfo, &(compute->commandBuffer))) + + VkCommandBufferBeginInfo beginInfo = {}; + beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; + beginInfo.flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT; + + ASSERT_VK(vkBeginCommandBuffer(compute->commandBuffer, &beginInfo)) + + vkCmdBindPipeline(compute->commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, compute->pipeline); + VkDescriptorSet descriptorSets[] = { + compute->particleBufferDescriptorSet, + compute->dtUniformBufferDescriptorSet, + compute->staticInUniformBufferDescriptorSet + }; + vkCmdBindDescriptorSets(compute->commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, compute->pipelineLayout, 0, 3, + descriptorSets, 0, NULL); + + vkCmdDispatch(compute->commandBuffer, WORKGROUP_SIZE_X, WORKGROUP_SIZE_Y, WORKGROUP_SIZE_Z); + + ASSERT_VK(vkEndCommandBuffer(compute->commandBuffer)) +} + +void createSemaphore(VkDevice device, VkSemaphore *semaphore) +{ + VkSemaphoreCreateInfo semaphoreCreateInfo = { .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO }; + ASSERT_VK(vkCreateSemaphore(device, &semaphoreCreateInfo, NULL, semaphore)); +} + +void shutdownComputeVulkan(Compute *compute) +{ + vkDeviceWaitIdle(compute->device); + + vkDestroySemaphore(compute->device, compute->semaphore, NULL); + + vkFreeMemory(compute->device, compute->particleBufferMemory, NULL); + vkFreeMemory(compute->device, compute->dtUniformBufferMemory, NULL); + vkFreeMemory(compute->device, compute->staticInUniformBufferMemory, NULL); + + vkDestroyBuffer(compute->device, compute->particleBuffer, NULL); + vkDestroyBuffer(compute->device, compute->dtUniformBuffer, NULL); + vkDestroyBuffer(compute->device, compute->staticInUniformBuffer, NULL); + + vkDestroyPipelineLayout(compute->device, compute->pipelineLayout, NULL); + + vkDestroyDescriptorPool(compute->device, compute->particleBufferDescriptorPool, NULL); + vkDestroyDescriptorPool(compute->device, compute->dtUniformBufferDescriptorPool, NULL); + vkDestroyDescriptorPool(compute->device, compute->staticInUniformBufferDescriptorPool, NULL); + + vkDestroyDescriptorSetLayout(compute->device, compute->particleBufferDescriptorSetLayout, NULL); + vkDestroyDescriptorSetLayout(compute->device, compute->dtUniformBufferDescriptorSetLayout, NULL); + vkDestroyDescriptorSetLayout(compute->device, compute->staticInUniformBufferDescriptorSetLayout, NULL); + + vkDestroyPipeline(compute->device, compute->pipeline, NULL); + + vkDestroyShaderModule(compute->device, compute->shaderModule, NULL); + + vkFreeCommandBuffers(compute->device, compute->commandPool, 1, &(compute->commandBuffer)); + + vkDestroyCommandPool(compute->device, compute->commandPool, NULL); + + vkDestroyDevice(compute->device, NULL); + + vkDestroyInstance(compute->instance, NULL); +} + +void createGraphicsSurface(Graphics *graphics, GLFWwindow *window) +{ + ASSERT_VK(glfwCreateWindowSurface(graphics->instance, window, NULL, &(graphics->surface))) +} + +void createSwapchain(Graphics *graphics) +{ + VkBool32 swapChainSupport; + ASSERT_VK(vkGetPhysicalDeviceSurfaceSupportKHR(graphics->physicalDevice, 0, graphics->surface, &swapChainSupport)) + if (!swapChainSupport) + { + printf("ERROR: Swap chain not supported!"); + assert(!swapChainSupport); + } + + VkExtent2D imageExtent = { WIDTH, HEIGHT }; + VkSwapchainCreateInfoKHR swapChainCreateInfo = {}; + swapChainCreateInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR; + swapChainCreateInfo.surface = graphics->surface; + swapChainCreateInfo.minImageCount = 1; + swapChainCreateInfo.imageFormat = VK_FORMAT_B8G8R8A8_UNORM; + swapChainCreateInfo.imageColorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR; + swapChainCreateInfo.imageExtent = imageExtent; + swapChainCreateInfo.imageArrayLayers = 1; + swapChainCreateInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; + swapChainCreateInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE; + swapChainCreateInfo.preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR; + swapChainCreateInfo.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; + swapChainCreateInfo.presentMode = VK_PRESENT_MODE_IMMEDIATE_KHR; + swapChainCreateInfo.clipped = VK_FALSE; + swapChainCreateInfo.oldSwapchain = VK_NULL_HANDLE; + + ASSERT_VK(vkCreateSwapchainKHR(graphics->device, &swapChainCreateInfo, NULL, &(graphics->swapChain))) + + vkGetSwapchainImagesKHR(graphics->device, graphics->swapChain, &(graphics->imageViewsSize), NULL); + VkImage swapChainImages[graphics->imageViewsSize]; + ASSERT_VK(vkGetSwapchainImagesKHR(graphics->device, graphics->swapChain, &(graphics->imageViewsSize), swapChainImages)) + + graphics->imageViews = malloc(graphics->imageViewsSize * sizeof(VkImageView)); + + for (int i = 0; i < graphics->imageViewsSize; i++) + { + VkImageViewCreateInfo imageViewInfo = {}; + VkComponentMapping componentMapping = { + VK_COMPONENT_SWIZZLE_IDENTITY, + VK_COMPONENT_SWIZZLE_IDENTITY, + VK_COMPONENT_SWIZZLE_IDENTITY, + VK_COMPONENT_SWIZZLE_IDENTITY + }; + VkImageSubresourceRange subresourceRange = { + VK_IMAGE_ASPECT_COLOR_BIT,0, 1, 0, 1 + }; + + imageViewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; + imageViewInfo.image = swapChainImages[i]; + imageViewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D; + imageViewInfo.format = VK_FORMAT_B8G8R8A8_UNORM; + imageViewInfo.components = componentMapping; + imageViewInfo.subresourceRange = subresourceRange; + + ASSERT_VK(vkCreateImageView(graphics->device, &imageViewInfo, NULL, &(graphics->imageViews[i]))) + } +} + +void createShaderStageInfo(VkPipelineShaderStageCreateInfo *shaderStageCreateInfo, VkShaderStageFlagBits shaderStageFlagBits, + VkShaderModule shaderModule) +{ + shaderStageCreateInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + shaderStageCreateInfo->stage = shaderStageFlagBits; + shaderStageCreateInfo->module = shaderModule; + shaderStageCreateInfo->pName = "main"; +} + +void createGraphicsPipeline(Graphics *graphics) +{ + VkVertexInputBindingDescription vertexInputBindingDescription; + vertexInputBindingDescription.binding = 0; + vertexInputBindingDescription.stride = PARTICLE_SIZE; + vertexInputBindingDescription.inputRate = VK_VERTEX_INPUT_RATE_VERTEX; + + VkVertexInputAttributeDescription positionVertexInputAttributeDescription; + positionVertexInputAttributeDescription.binding = 0; + positionVertexInputAttributeDescription.location = 0; + positionVertexInputAttributeDescription.format = VK_FORMAT_R32G32B32_SFLOAT; + positionVertexInputAttributeDescription.offset = 0; + + VkVertexInputAttributeDescription colInVertexInputAttributeDescription; + colInVertexInputAttributeDescription.binding = 0; + colInVertexInputAttributeDescription.location = 1; + colInVertexInputAttributeDescription.format = VK_FORMAT_R32G32B32_SFLOAT; + colInVertexInputAttributeDescription.offset = 24; + + VkVertexInputAttributeDescription vertexInputAttributeDescription[2] = { + positionVertexInputAttributeDescription, + colInVertexInputAttributeDescription + }; + + VkPipelineVertexInputStateCreateInfo vertexInputStateInfo = {}; + vertexInputStateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; + vertexInputStateInfo.vertexBindingDescriptionCount = 1; + vertexInputStateInfo.pVertexBindingDescriptions = &vertexInputBindingDescription; + vertexInputStateInfo.vertexAttributeDescriptionCount = 2; + vertexInputStateInfo.pVertexAttributeDescriptions = vertexInputAttributeDescription; + + createShaderModule(graphics->device, "./vulkan/vert.spv", &(graphics->vertexShaderModule)); + createShaderModule(graphics->device, "./vulkan/frag.spv", &(graphics->fragmentShaderModule)); + + VkPipelineShaderStageCreateInfo vertexShaderStageInfo = {}; + createShaderStageInfo(&vertexShaderStageInfo, VK_SHADER_STAGE_VERTEX_BIT, graphics->vertexShaderModule); + VkPipelineShaderStageCreateInfo fragmentShaderStageInfo = {}; + createShaderStageInfo(&fragmentShaderStageInfo, VK_SHADER_STAGE_FRAGMENT_BIT, graphics->fragmentShaderModule); + + VkPipelineShaderStageCreateInfo shaderStages[] = { + vertexShaderStageInfo, + fragmentShaderStageInfo + }; + + VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateInfo = {}; + inputAssemblyStateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; + inputAssemblyStateInfo.topology = VK_PRIMITIVE_TOPOLOGY_POINT_LIST; + inputAssemblyStateInfo.primitiveRestartEnable = VK_FALSE; + + VkViewport viewport = {}; viewport.x = 0.0f; viewport.y = 0.0f; - viewport.width = width; - viewport.height = height; + viewport.width = WIDTH; + viewport.height = HEIGHT; viewport.minDepth = 0.0f; viewport.maxDepth = 1.0f; - VkRect2D scissor = { {0, 0}, {width, height} }; + VkRect2D scissor = { {0, 0}, {WIDTH, HEIGHT} }; - viewportStateInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; - viewportStateInfo->pNext = NULL; - viewportStateInfo->flags = 0; - viewportStateInfo->viewportCount = 1; - viewportStateInfo->pViewports = &viewport; - viewportStateInfo->scissorCount = 1; - viewportStateInfo->pScissors = &scissor; + VkPipelineViewportStateCreateInfo viewportStateInfo = {}; + viewportStateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; + viewportStateInfo.viewportCount = 1; + viewportStateInfo.pViewports = &viewport; + viewportStateInfo.scissorCount = 1; + viewportStateInfo.pScissors = &scissor; + + VkPipelineRasterizationStateCreateInfo rasterizationStateInfo = {}; + rasterizationStateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; + rasterizationStateInfo.depthClampEnable = VK_FALSE; + rasterizationStateInfo.rasterizerDiscardEnable = VK_FALSE; + rasterizationStateInfo.polygonMode = VK_POLYGON_MODE_FILL; + rasterizationStateInfo.cullMode = VK_CULL_MODE_BACK_BIT; + rasterizationStateInfo.frontFace = VK_FRONT_FACE_CLOCKWISE; + rasterizationStateInfo.depthBiasEnable = VK_FALSE; + rasterizationStateInfo.depthBiasConstantFactor = 0.0f; + rasterizationStateInfo.depthBiasClamp = 0.0f; + rasterizationStateInfo.depthBiasSlopeFactor = 0.0f; + rasterizationStateInfo.lineWidth = 1.0f; + + VkPipelineMultisampleStateCreateInfo multisampleStateInfo = {}; + multisampleStateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; + multisampleStateInfo.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; + multisampleStateInfo.sampleShadingEnable = VK_FALSE; + multisampleStateInfo.minSampleShading = 1.0f; + multisampleStateInfo.alphaToCoverageEnable = VK_FALSE; + multisampleStateInfo.alphaToOneEnable = VK_FALSE; + + VkPipelineColorBlendAttachmentState colorBlendAttachmentState = {}; + colorBlendAttachmentState.blendEnable = VK_FALSE; + colorBlendAttachmentState.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA; + colorBlendAttachmentState.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; + colorBlendAttachmentState.colorBlendOp = VK_BLEND_OP_ADD; + colorBlendAttachmentState.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE; + colorBlendAttachmentState.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO; + colorBlendAttachmentState.alphaBlendOp = VK_BLEND_OP_ADD; + colorBlendAttachmentState.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; + + VkPipelineColorBlendStateCreateInfo colorBlendStateInfo = {}; + colorBlendStateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; + colorBlendStateInfo.logicOpEnable = VK_FALSE; + colorBlendStateInfo.logicOp = VK_LOGIC_OP_NO_OP; + colorBlendStateInfo.attachmentCount = 1; + colorBlendStateInfo.pAttachments = &colorBlendAttachmentState; + colorBlendStateInfo.blendConstants[0] = 0.0f; + colorBlendStateInfo.blendConstants[1] = 0.0f; + colorBlendStateInfo.blendConstants[2] = 0.0f; + colorBlendStateInfo.blendConstants[3] = 0.0f; + + VkPipelineLayoutCreateInfo layoutInfo = {}; + layoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; + + ASSERT_VK(vkCreatePipelineLayout(graphics->device, &layoutInfo, NULL, &(graphics->pipelineLayout))) + + VkAttachmentDescription attachmentDescription = {}; + attachmentDescription.format = VK_FORMAT_B8G8R8A8_UNORM; + attachmentDescription.samples = VK_SAMPLE_COUNT_1_BIT; + attachmentDescription.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; + attachmentDescription.storeOp = VK_ATTACHMENT_STORE_OP_STORE; + attachmentDescription.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; + attachmentDescription.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; + attachmentDescription.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; + attachmentDescription.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; + + VkAttachmentReference attachmentReference = {}; + attachmentReference.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + + VkSubpassDescription subpassDescription = {}; + subpassDescription.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; + subpassDescription.colorAttachmentCount = 1; + subpassDescription.pColorAttachments = &attachmentReference; + + VkSubpassDependency subpassDependency = {}; + subpassDependency.srcSubpass = VK_SUBPASS_EXTERNAL; + subpassDependency.dstSubpass = 0; + subpassDependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; + subpassDependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; + subpassDependency.srcAccessMask = 0; + subpassDependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + + VkRenderPassCreateInfo renderPassInfo = {}; + renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; + renderPassInfo.attachmentCount = 1; + renderPassInfo.pAttachments = &attachmentDescription; + renderPassInfo.subpassCount = 1; + renderPassInfo.pSubpasses = &subpassDescription; + renderPassInfo.dependencyCount = 1; + renderPassInfo.pDependencies = &subpassDependency; + + + ASSERT_VK(vkCreateRenderPass(graphics->device, &renderPassInfo, NULL, &(graphics->renderPass))) + + VkGraphicsPipelineCreateInfo graphicsPipelineInfo = {}; + graphicsPipelineInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; + graphicsPipelineInfo.stageCount = 2; + graphicsPipelineInfo.pStages = shaderStages; + graphicsPipelineInfo.pVertexInputState = &vertexInputStateInfo; + graphicsPipelineInfo.pInputAssemblyState = &inputAssemblyStateInfo; + graphicsPipelineInfo.pViewportState = &viewportStateInfo; + graphicsPipelineInfo.pRasterizationState = &rasterizationStateInfo; + graphicsPipelineInfo.pMultisampleState = &multisampleStateInfo; + graphicsPipelineInfo.pColorBlendState = &colorBlendStateInfo; + graphicsPipelineInfo.layout = graphics->pipelineLayout; + graphicsPipelineInfo.renderPass = graphics->renderPass; + graphicsPipelineInfo.basePipelineHandle = VK_NULL_HANDLE; + graphicsPipelineInfo.basePipelineIndex = -1; + + ASSERT_VK(vkCreateGraphicsPipelines(graphics->device, VK_NULL_HANDLE, 1, &graphicsPipelineInfo, NULL, &(graphics->pipeline))) } -void createRasterizationStateInfo(VkPipelineRasterizationStateCreateInfo *rasterizationStateInfo, VkPolygonMode polygonMode) +void createFramebuffer(Graphics *graphics) { - rasterizationStateInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; - rasterizationStateInfo->pNext = NULL; - rasterizationStateInfo->flags = 0; - rasterizationStateInfo->depthClampEnable = VK_FALSE; - rasterizationStateInfo->rasterizerDiscardEnable = VK_FALSE; - rasterizationStateInfo->polygonMode = polygonMode; - rasterizationStateInfo->cullMode = VK_CULL_MODE_BACK_BIT; - rasterizationStateInfo->frontFace = VK_FRONT_FACE_CLOCKWISE; - rasterizationStateInfo->depthBiasEnable = VK_FALSE; - rasterizationStateInfo->depthBiasConstantFactor = 0.0f; - rasterizationStateInfo->depthBiasClamp = 0.0f; - rasterizationStateInfo->depthBiasSlopeFactor = 0.0f; - rasterizationStateInfo->lineWidth = 1.0f; -} - -void createMultisampleStateInfo(VkPipelineMultisampleStateCreateInfo *multisampleStateInfo) -{ - multisampleStateInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; - multisampleStateInfo->pNext = NULL; - multisampleStateInfo->flags = 0; - multisampleStateInfo->rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; - multisampleStateInfo->sampleShadingEnable = VK_FALSE; - multisampleStateInfo->minSampleShading = 1.0f; - multisampleStateInfo->pSampleMask = NULL; - multisampleStateInfo->alphaToCoverageEnable = VK_FALSE; - multisampleStateInfo->alphaToOneEnable = VK_FALSE; -} - -void createColorBlendAttachmentStateInfo(VkPipelineColorBlendAttachmentState *colorBlendAttachmentState) -{ - colorBlendAttachmentState->blendEnable = VK_FALSE; - colorBlendAttachmentState->srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA; - colorBlendAttachmentState->dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; - colorBlendAttachmentState->colorBlendOp = VK_BLEND_OP_ADD; - colorBlendAttachmentState->srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE; - colorBlendAttachmentState->dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO; - colorBlendAttachmentState->alphaBlendOp = VK_BLEND_OP_ADD; - colorBlendAttachmentState->colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; -} - -void createColorBlendStateInfo(VkPipelineColorBlendStateCreateInfo *colorBlendStateInfo, VkPipelineColorBlendAttachmentState *blendAttachments, uint32_t blendAttachmentsSize) -{ - colorBlendStateInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; - colorBlendStateInfo->pNext = NULL; - colorBlendStateInfo->flags = 0; - colorBlendStateInfo->logicOpEnable = VK_FALSE; - colorBlendStateInfo->logicOp = VK_LOGIC_OP_NO_OP; - colorBlendStateInfo->attachmentCount = blendAttachmentsSize; - colorBlendStateInfo->pAttachments = blendAttachments; - colorBlendStateInfo->blendConstants[0] = 0.0f; - colorBlendStateInfo->blendConstants[1] = 0.0f; - colorBlendStateInfo->blendConstants[2] = 0.0f; - colorBlendStateInfo->blendConstants[3] = 0.0f; -} - -void createLayoutInfo(VkPipelineLayoutCreateInfo *layoutInfo, VkDescriptorSetLayout *setLayouts, uint32_t setLayoutSize) -{ - layoutInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; - layoutInfo->pNext = NULL; - layoutInfo->flags = 0; - layoutInfo->setLayoutCount = setLayoutSize; - layoutInfo->pSetLayouts = setLayouts; - layoutInfo->pushConstantRangeCount = 0; - layoutInfo->pPushConstantRanges = NULL; -} - -void printStats(VkPhysicalDevice *physicalDevice, VkSurfaceKHR *surface) -{ - // Device Properties - VkPhysicalDeviceProperties properties; - vkGetPhysicalDeviceProperties(*physicalDevice, &properties); - - printf("--------- DEVICE PROPERTIES ---------\n"); - uint32_t apiVersion = properties.apiVersion; - printf("Name: %s\n", properties.deviceName); - printf("API Version: %d.%d.%d\n", VK_VERSION_MAJOR(apiVersion), VK_VERSION_MINOR(apiVersion), VK_VERSION_PATCH(apiVersion)); - - // Features - VkPhysicalDeviceFeatures features; - vkGetPhysicalDeviceFeatures(*physicalDevice, &features); - - printf("\n--------- FEATURES ---------\n"); - printf("Geometry Shader: %s\n", (BOOL_LITERAL(features.geometryShader))); - printf("Tessellation Shader: %s\n", (BOOL_LITERAL(features.tessellationShader))); - - // Memory Properties - VkPhysicalDeviceMemoryProperties memoryProperties; - vkGetPhysicalDeviceMemoryProperties(*physicalDevice, &memoryProperties); - - printf("\n--------- MEMORY PROPERTIES ---------\n"); - printf("Heapsize: %llu Byte / %f GiB\n", memoryProperties.memoryHeaps->size, - (HUMAN_READABLE(memoryProperties.memoryHeaps->size))); - - // Queue Properties - uint32_t amountQueueFamilies = 0; - vkGetPhysicalDeviceQueueFamilyProperties(*physicalDevice, &amountQueueFamilies, NULL); - VkQueueFamilyProperties familyProperties[amountQueueFamilies]; - vkGetPhysicalDeviceQueueFamilyProperties(*physicalDevice, &amountQueueFamilies, familyProperties); - - printf("\n--------- QUEUE PROPERTIES ---------\n"); - printf("Queue Families Amount: %d\n", amountQueueFamilies); - - for (int i = 0; i < amountQueueFamilies; i++) + graphics->framebuffers = malloc(graphics->imageViewsSize * sizeof(VkFramebuffer)); + for (int i = 0; i < graphics->imageViewsSize; ++i) { - printf("-- Queue Family #%d --\n", i); - printf(" Graphics bit: %s\n", (BOOL_LITERAL((familyProperties[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) != 0))); - printf(" Compute bit: %s\n", (BOOL_LITERAL((familyProperties[i].queueFlags & VK_QUEUE_COMPUTE_BIT) != 0))); - printf(" Transfer bit: %s\n", (BOOL_LITERAL((familyProperties[i].queueFlags & VK_QUEUE_TRANSFER_BIT) != 0))); - printf(" Sparse Binding bit: %s\n", (BOOL_LITERAL((familyProperties[i].queueFlags & VK_QUEUE_SPARSE_BINDING_BIT) != 0))); - printf(" Queue Count: %d\n", familyProperties[i].queueCount); + VkFramebufferCreateInfo framebufferInfo = {}; + framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; + framebufferInfo.renderPass = graphics->renderPass; + framebufferInfo.attachmentCount = 1; + framebufferInfo.pAttachments = &(graphics->imageViews[i]); + framebufferInfo.width = WIDTH; + framebufferInfo.height = HEIGHT; + framebufferInfo.layers = 1; + + ASSERT_VK(vkCreateFramebuffer(graphics->device, &framebufferInfo, NULL, &(graphics->framebuffers[i]))) + } +} + +void createGraphicsCommandBuffers(Graphics *graphics) +{ + VkCommandPoolCreateInfo commandPoolInfo = {}; + commandPoolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; + commandPoolInfo.queueFamilyIndex = graphics->queueFamilyIndex; + + ASSERT_VK(vkCreateCommandPool(graphics->device, &commandPoolInfo, NULL, &(graphics->commandPool))) + + VkCommandBufferAllocateInfo commandBufferAllocateInfo = {}; + commandBufferAllocateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; + commandBufferAllocateInfo.commandPool = graphics->commandPool; + commandBufferAllocateInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; + commandBufferAllocateInfo.commandBufferCount = graphics->imageViewsSize; + + graphics->commandBuffers = malloc(graphics->imageViewsSize * sizeof(VkCommandBuffer)); + + ASSERT_VK(vkAllocateCommandBuffers(graphics->device, &commandBufferAllocateInfo, graphics->commandBuffers)) + + VkCommandBufferBeginInfo commandBufferBeginInfo = {}; + commandBufferBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; + commandBufferBeginInfo.flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT; + + VkRect2D renderArea = { {0, 0}, {WIDTH, HEIGHT} }; + VkClearValue clearValue = {0, 0, 0, 1}; + + for (int i = 0; i < graphics->imageViewsSize; i++) + { + ASSERT_VK(vkBeginCommandBuffer(graphics->commandBuffers[i], &commandBufferBeginInfo)) + + VkRenderPassBeginInfo renderPassBeginInfo = {}; + renderPassBeginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; + renderPassBeginInfo.renderPass = graphics->renderPass; + renderPassBeginInfo.framebuffer = graphics->framebuffers[i]; + renderPassBeginInfo.renderArea = renderArea; + renderPassBeginInfo.clearValueCount = 1; + renderPassBeginInfo.pClearValues = &clearValue; + + vkCmdBeginRenderPass(graphics->commandBuffers[i], &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); + + vkCmdBindPipeline(graphics->commandBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, graphics->pipeline); + + VkDeviceSize offsets[1] = { 0 }; + vkCmdBindVertexBuffers(graphics->commandBuffers[i], 0, 1, &(graphics->particleBuffer), offsets); + + vkCmdDraw(graphics->commandBuffers[i], PARTICLE_AMOUNT, 1, 0, 0); + + vkCmdEndRenderPass(graphics->commandBuffers[i]); + + ASSERT_VK(vkEndCommandBuffer(graphics->commandBuffers[i])) + } +} + +void shutdownGraphicsVulkan(Graphics *graphics) +{ + vkDeviceWaitIdle(graphics->device); + + for (int i = 0; i < graphics->imageViewsSize; ++i) + { + vkDestroyFramebuffer(graphics->device, graphics->framebuffers[i], NULL); } - // Surface Capabilities - VkSurfaceCapabilitiesKHR surfaceCapabilities; - vkGetPhysicalDeviceSurfaceCapabilitiesKHR(*physicalDevice, *surface, &surfaceCapabilities); - printf("\n--------- SURFACE CAPABILITIES ---------\n"); - printf(" Min Image Count: %d\n", surfaceCapabilities.minImageCount); - printf(" Max Image Count: %d\n", surfaceCapabilities.maxImageCount); - printf(" Current Extent: (%d; %d)\n", surfaceCapabilities.currentExtent.width, surfaceCapabilities.currentExtent.height); - printf(" Min Image Extent: (%d; %d)\n", surfaceCapabilities.minImageExtent.width, surfaceCapabilities.minImageExtent.height); - printf(" Max Image Extent: (%d; %d)\n", surfaceCapabilities.maxImageExtent.width, surfaceCapabilities.maxImageExtent.height); - printf(" Max Image Array Layers: %d\n", surfaceCapabilities.maxImageArrayLayers); - printf(" Supported Transforms: %d\n", surfaceCapabilities.supportedTransforms); - printf(" Current Transform: %d\n", surfaceCapabilities.currentTransform); - printf(" Supported Composite Alpha: %d\n", surfaceCapabilities.supportedCompositeAlpha); - printf(" Supported Usage Flags: %d\n", surfaceCapabilities.supportedUsageFlags); + vkDestroyCommandPool(graphics->device, graphics->commandPool, NULL); - // Surface Formats - uint32_t amountFormats; - vkGetPhysicalDeviceSurfaceFormatsKHR(*physicalDevice, *surface, &amountFormats, NULL); - VkSurfaceFormatKHR formats[amountFormats]; - vkGetPhysicalDeviceSurfaceFormatsKHR(*physicalDevice, *surface, &amountFormats, formats); + vkDestroySemaphore(graphics->device, graphics->semaphore, NULL); + vkDestroySemaphore(graphics->device, graphics->renderComplete, NULL); + vkDestroySemaphore(graphics->device, graphics->presentComplete, NULL); - printf("\n--------- SURFACE FORMATS ---------\n"); - printf("Surface Formats Amount: %d\n", amountFormats); + vkDestroyPipelineLayout(graphics->device, graphics->pipelineLayout, NULL); - for (int i = 0; i < amountFormats; i++) + vkDestroyRenderPass(graphics->device, graphics->renderPass, NULL); + + vkDestroyPipeline(graphics->device, graphics->pipeline, NULL); + + vkDestroyShaderModule(graphics->device, graphics->fragmentShaderModule, NULL); + vkDestroyShaderModule(graphics->device, graphics->vertexShaderModule, NULL); + + for (int i = 0; i < graphics->imageViewsSize; ++i) { - printf("-- Surface Format #%d --\n", i); - printf(" Format: %d\n", formats[i].format); + vkDestroyImageView(graphics->device, graphics->imageViews[i], NULL); } - // Presentation Modes - uint32_t amountPresentModes; - vkGetPhysicalDeviceSurfacePresentModesKHR(*physicalDevice, *surface, &amountPresentModes, NULL); - VkPresentModeKHR presentModes[amountPresentModes]; - vkGetPhysicalDeviceSurfacePresentModesKHR(*physicalDevice, *surface, &amountPresentModes, presentModes); + vkDestroySwapchainKHR(graphics->device, graphics->swapChain, NULL); - printf("\n--------- PRESENTATION MODES ---------\n"); - printf("Presentation Modes Amount: %d\n", amountPresentModes); - - for (int i = 0; i < amountPresentModes; ++i) - { - printf("-- Present Mode #%d --\n", i); - printf(" Mode: %d\n", presentModes[i]); - } + vkDestroySurfaceKHR(graphics->instance, graphics->surface, NULL); } \ No newline at end of file diff --git a/initVulkan.h b/initVulkan.h index 2874103..9c706d7 100644 --- a/initVulkan.h +++ b/initVulkan.h @@ -1,11 +1,12 @@ #include #include -#include +#include #include "vulkan/vulkan.h" #define GLFW_INCLUDE_VULKAN #include "GLFW/glfw3.h" +#include "particlesystem.h" #include "utils.h" #define APP_NAME "Informatikprojekt - Vulkan" @@ -13,62 +14,134 @@ #define ENGINE_NAME "rwu_particles" #define ENGINE_VERSION VK_MAKE_VERSION(0, 0, 0) +#define PARTICLE_AMOUNT 1000000 +#define PARTICLE_SIZE (3 * sizeof(vector3f) + sizeof(float)) +#define WORKGROUP_SIZE_X 1024 +#define WORKGROUP_SIZE_Y 1 +#define WORKGROUP_SIZE_Z 1 + #define SUCCESS 0 #define FAILURE -1 -#define ASSERT_SUCCESS(res) { if (res != SUCCESS) { printf("Error-Code: %d", res); return FAILURE; } } -#define ASSERT_VK_SUCCESS(res) { if (res != VK_SUCCESS) { printf("Error-Code: %d", res); return FAILURE; } } +#define ASSERT_VK(f) { \ + VkResult res = (f); \ + if (res != VK_SUCCESS) { \ + printf("Fatal : VkResult is %d in %s at line %d\n", res, __FILE__, __LINE__); \ + assert(res == VK_SUCCESS); \ + } \ +} #define ASSERT_GLFW_SUCCESS(res) { if (res != GLFW_TRUE) { printf("Error-Code: %d", res); return FAILURE; } } -#define BOOL_LITERAL(val) val ? "True" : "False" -#define HUMAN_READABLE(val) val * 9.313226e-10 -int initVulkan(VkInstance *vkInstance, VkDevice *device, VkSurfaceKHR *surface, GLFWwindow *window, - VkSwapchainKHR *swapChain, VkImageView **imageViews, uint32_t *amountImages); -void createAppInfo(VkApplicationInfo *appInfo); -void createInstanceInfo(VkApplicationInfo *appInfo, VkInstanceCreateInfo *instanceInfo); -void createQueueInfo(VkDeviceQueueCreateInfo *queueInfo); -void createDeviceInfo(VkDeviceQueueCreateInfo *queueInfo, VkDeviceCreateInfo *deviceInfo, - VkPhysicalDeviceFeatures *features); -void createImageViewInfo(VkImageViewCreateInfo *imageViewInfo, VkImage *swapChainImages, int index); -void createSwapChainInfo(VkSwapchainCreateInfoKHR *swapChainCreateInfo, VkSurfaceKHR *surface); -void createShaderStageInfo(VkPipelineShaderStageCreateInfo *shaderStageInfo, VkShaderStageFlagBits shaderStageBit, - VkShaderModule shaderModule, const char *entryPointName); -int createShaderModule(VkDevice device, VkShaderModule *shaderModule, const char *shaderSource, long sourceSize); -void createPipelineVertexInputStateInfo(VkPipelineVertexInputStateCreateInfo *vertexInputStateInfo, - VkVertexInputAttributeDescription *attributes, uint32_t atrributesSize); -void createInputAssemblyStateInfo(VkPipelineInputAssemblyStateCreateInfo *inputAssemblyStateInfo, VkPrimitiveTopology topology); -void createViewportStateInfo(VkPipelineViewportStateCreateInfo *viewportStateInfo, float width, float height); -void createRasterizationStateInfo(VkPipelineRasterizationStateCreateInfo *rasterizationStateInfo, VkPolygonMode polygonMode); -void createMultisampleStateInfo(VkPipelineMultisampleStateCreateInfo *multisampleStateInfo); -void createColorBlendAttachmentStateInfo(VkPipelineColorBlendAttachmentState *colorBlendAttachmentState); -void createColorBlendStateInfo(VkPipelineColorBlendStateCreateInfo *colorBlendStateInfo, - VkPipelineColorBlendAttachmentState *blendAttachments, uint32_t blendAttachmentsSize); -void createLayoutInfo(VkPipelineLayoutCreateInfo *layoutInfo, VkDescriptorSetLayout *setLayouts, uint32_t setLayoutSize); -void createAttachmentDescription(VkAttachmentDescription *attachmentDescription); -void createAttachmentReference(VkAttachmentReference *attachmentReference, uint32_t attachment); -void createSubpassDescription(VkSubpassDescription *subpassDescription, VkPipelineBindPoint bindPoint, - VkAttachmentReference *attachmentReference); -void createRenderPassInfo(VkRenderPassCreateInfo *renderPassInfo, VkAttachmentDescription *attachmentDescriptions, - VkSubpassDescription *subpassDescriptions); -void createSemaphoreInfo(VkSemaphoreCreateInfo *semaphoreInfo); -void createGraphicsPipelineInfo(VkGraphicsPipelineCreateInfo *graphicsPipelineInfo, - VkPipelineShaderStageCreateInfo *shaderStages, - VkPipelineVertexInputStateCreateInfo *vertexInputState, - VkPipelineInputAssemblyStateCreateInfo *inputAssemblyState, - VkPipelineViewportStateCreateInfo *viewportState, - VkPipelineRasterizationStateCreateInfo *rasterizationState, - VkPipelineMultisampleStateCreateInfo *multisampleState, - VkPipelineColorBlendStateCreateInfo *colorBlendState, VkPipelineLayout *pipelineLayout, - VkRenderPass *renderPass); -void createFramebufferInfo(VkFramebufferCreateInfo *framebufferInfo, VkRenderPass *renderPass, VkImageView *imageView); -void createCommandPoolInfo(VkCommandPoolCreateInfo *commandPoolInfo, uint32_t queueFamilyIndex); -void createCommandBufferAllocateInfo(VkCommandBufferAllocateInfo *commandBufferAllocateInfo, VkCommandPool *commandPool, uint32_t amountImages); -void createCommandBufferBeginInfo(VkCommandBufferBeginInfo *commandBufferBeginInfo); -void createRenderPassBeginInfo(VkRenderPassBeginInfo *renderPassBeginInfo, VkRenderPass *renderPass, VkFramebuffer *framebuffer); -void shutdownVulkan(VkInstance *vkInstance, VkDevice *device, VkSurfaceKHR *surface, VkSwapchainKHR *swapChain, - VkImageView *imageViews, uint32_t imageViewsSize, VkShaderModule *modules, - uint32_t shaderModulesSize, VkPipelineLayout *pipelineLayouts, uint32_t pipelineLayoutsSize, - VkRenderPass *renderPasses, uint32_t renderPassesSize, VkPipeline *pipelines, - uint32_t pipelinesSize, VkFramebuffer *framebuffers, VkCommandPool *commandPool, - VkCommandBuffer *commandBuffers, VkSemaphore *semaphores, uint32_t semaphoresSize); +typedef struct dt { + float dt; +} Dt; + +typedef struct staticIn { + float x; + float y; + float z; + unsigned int maxParticles; +} StaticIn; + +typedef struct compute { + VkInstance instance; + + VkPhysicalDevice physicalDevice; + VkDevice device; + + VkPipeline pipeline; + VkPipelineLayout pipelineLayout; + VkShaderModule shaderModule; + + VkCommandPool commandPool; + VkCommandBuffer commandBuffer; + + VkDescriptorSetLayout particleBufferDescriptorSetLayout; + VkDescriptorPool particleBufferDescriptorPool; + VkDescriptorSet particleBufferDescriptorSet; + VkBuffer particleBuffer; + VkDeviceMemory particleBufferMemory; + uint32_t particleBufferSize; + + VkDescriptorSetLayout dtUniformBufferDescriptorSetLayout; + VkDescriptorPool dtUniformBufferDescriptorPool; + VkDescriptorSet dtUniformBufferDescriptorSet; + VkBuffer dtUniformBuffer; + VkDeviceMemory dtUniformBufferMemory; + uint32_t dtUniformBufferSize; + + VkDescriptorSetLayout staticInUniformBufferDescriptorSetLayout; + VkDescriptorPool staticInUniformBufferDescriptorPool; + VkDescriptorSet staticInUniformBufferDescriptorSet; + VkBuffer staticInUniformBuffer; + VkDeviceMemory staticInUniformBufferMemory; + uint32_t staticInUniformBufferSize; + + VkQueue queue; + uint32_t queueFamilyIndex; + + VkSemaphore semaphore; +} Compute; + +typedef struct graphics { + VkInstance instance; + + VkPhysicalDevice physicalDevice; + VkDevice device; + + VkSurfaceKHR surface; + VkSwapchainKHR swapChain; + + VkImageView *imageViews; + uint32_t imageViewsSize; + + VkRenderPass renderPass; + VkFramebuffer *framebuffers; + + VkPipeline pipeline; + VkPipelineLayout pipelineLayout; + VkShaderModule vertexShaderModule; + VkShaderModule fragmentShaderModule; + + VkCommandPool commandPool; + VkCommandBuffer *commandBuffers; + + VkBuffer particleBuffer; + uint32_t particleBufferSize; + + VkQueue queue; + uint32_t queueFamilyIndex; + + VkSemaphore renderComplete; + VkSemaphore presentComplete; + VkSemaphore semaphore; +} Graphics; + +// Shutdown void shutdownGLFW(GLFWwindow *window); -void printStats(VkPhysicalDevice *physicalDevice, VkSurfaceKHR *surface); +void shutdownComputeVulkan(Compute *compute); +void shutdownGraphicsVulkan(Graphics *graphics); + +// General +void createInstance(Compute *compute, Graphics *graphics); +void findPhysicalDevice(Compute *compute, Graphics *graphics); +void createDevice(Compute *compute, Graphics *graphics); +void createParticleBuffer(Compute *compute, Graphics *graphics); + +// Compute +void createComputeBuffers(Compute *compute); +void createComputeDescriptorSetLayouts(Compute *compute); +void createComputeDescriptorSets(Compute *compute); +void createComputePipeline(Compute *compute); +void fillComputeBuffers(Compute *compute, float *particles, Dt *dtData, StaticIn *staticInData); +void createComputeCommandBuffer(Compute *compute); + +// Graphics +void createGraphicsSurface(Graphics *graphics, GLFWwindow *window); +void createSwapchain(Graphics *graphics); +void createGraphicsPipeline(Graphics *graphics); +void createFramebuffer(Graphics *graphics); +void createGraphicsCommandBuffers(Graphics *graphics); + +// ELse +void mapBufferMemory(Compute *compute, VkDeviceMemory memory, void *inputData, uint32_t dataSize); +void createSemaphore(VkDevice device, VkSemaphore *semaphore); diff --git a/newVulkan/initVulkan.c b/newVulkan/initVulkan.c deleted file mode 100644 index 0ee5c5f..0000000 --- a/newVulkan/initVulkan.c +++ /dev/null @@ -1,896 +0,0 @@ -#include "initVulkan.h" -#include - -void shutdownGLFW(GLFWwindow *window) -{ - glfwDestroyWindow(window); - glfwTerminate(); -} - -void createInstance(Compute *compute, Graphics *graphics) -{ - GLuint enabledLayerSize = 0; - const char **enabledLayer; - GLuint extensionsSize; - const char **glfwExtensions = glfwGetRequiredInstanceExtensions(&extensionsSize); - - #ifndef NDEBUG - enabledLayerSize = 1; - enabledLayer = malloc(sizeof(char *)); - enabledLayer[0] = "VK_LAYER_LUNARG_standard_validation"; - #endif - - VkApplicationInfo applicationInfo = {}; - applicationInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; - applicationInfo.pApplicationName = APP_NAME; - applicationInfo.applicationVersion = APP_VERSION; - applicationInfo.pEngineName = ENGINE_NAME; - applicationInfo.engineVersion = ENGINE_VERSION; - applicationInfo.apiVersion = VK_API_VERSION_1_2; - - VkInstanceCreateInfo instanceCreateInfo = {}; - instanceCreateInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; - instanceCreateInfo.flags = 0; - instanceCreateInfo.pApplicationInfo = &applicationInfo; - instanceCreateInfo.enabledLayerCount = enabledLayerSize; - instanceCreateInfo.ppEnabledLayerNames = enabledLayer; - instanceCreateInfo.enabledExtensionCount = extensionsSize; - instanceCreateInfo.ppEnabledExtensionNames = glfwExtensions; - - ASSERT_VK(vkCreateInstance(&instanceCreateInfo, NULL, &(compute->instance))) - - graphics->instance = compute->instance; -} - -void findPhysicalDevice(Compute *compute, Graphics *graphics) -{ - uint32_t devicesSize; - vkEnumeratePhysicalDevices(compute->instance, &devicesSize, NULL); - - if (devicesSize <= 0) - { - printf("Fatal : No device found with Vulkan support!"); - assert(devicesSize > 0); - } - - VkPhysicalDevice physicalDevices[devicesSize]; - vkEnumeratePhysicalDevices(compute->instance, &devicesSize, physicalDevices); - - for (int i = 0; i < devicesSize; ++i) - { - VkPhysicalDeviceProperties deviceProperties = {}; - vkGetPhysicalDeviceProperties(physicalDevices[i], &deviceProperties); - - if (WORKGROUP_SIZE_X <= deviceProperties.limits.maxComputeWorkGroupSize[0] - && PARTICLE_AMOUNT / WORKGROUP_SIZE_X <= deviceProperties.limits.maxComputeWorkGroupCount[0] - && (uint32_t) (PARTICLE_SIZE * PARTICLE_AMOUNT) <= deviceProperties.limits.maxStorageBufferRange) - { - compute->physicalDevice = physicalDevices[i]; - break; - } - } - - if (!compute->physicalDevice) - { - printf("Fatal : No device found with capable limits!"); - assert(compute->physicalDevice); - } - - graphics->physicalDevice = compute->physicalDevice; -} - -uint32_t getQueueFamilyIndex(VkPhysicalDevice physicalDevice, VkQueueFlagBits queueFlagBits, int noGraphics) -{ - uint32_t queueFamiliesSize; - vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueFamiliesSize, NULL); - VkQueueFamilyProperties queueFamilies[queueFamiliesSize]; - vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueFamiliesSize, queueFamilies); - - for (uint32_t i = 0; i < queueFamiliesSize; ++i) - { - if (noGraphics && (queueFamilies[i].queueFlags & VK_QUEUE_GRAPHICS_BIT)) - { - } - else if ((queueFamilies[i].queueFlags & queueFlagBits) == queueFlagBits) - { - return i; - } - } - - return UINT32_MAX; -} - -void createDevice(Compute *compute, Graphics *graphics) -{ - compute->queueFamilyIndex = getQueueFamilyIndex(compute->physicalDevice, VK_QUEUE_COMPUTE_BIT, 1); - if (compute->queueFamilyIndex == UINT32_MAX) - { - printf("ERROR: No Queue family found with desired capabilities!\n"); - assert( compute->queueFamilyIndex < UINT32_MAX); - } - - float queuePriority = 1.0f; - VkDeviceQueueCreateInfo computeDeviceQueueCreateInfo = {}; - computeDeviceQueueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; - computeDeviceQueueCreateInfo.queueFamilyIndex = compute->queueFamilyIndex; - computeDeviceQueueCreateInfo.queueCount = 1; - computeDeviceQueueCreateInfo.pQueuePriorities = &queuePriority; - - graphics->queueFamilyIndex = getQueueFamilyIndex(graphics->physicalDevice, VK_QUEUE_GRAPHICS_BIT, 0); - if (graphics->queueFamilyIndex == UINT32_MAX) - { - printf("ERROR: No Queue family found with desired capabilities!\n"); - assert( compute->queueFamilyIndex < UINT32_MAX); - } - - VkDeviceQueueCreateInfo graphicsDeviceQueueCreateInfo = {}; - graphicsDeviceQueueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; - graphicsDeviceQueueCreateInfo.queueFamilyIndex = graphics->queueFamilyIndex; - graphicsDeviceQueueCreateInfo.queueCount = 1; - graphicsDeviceQueueCreateInfo.pQueuePriorities = &queuePriority; - - VkDeviceQueueCreateInfo deviceQueueCreateInfos[2] = { - computeDeviceQueueCreateInfo, - graphicsDeviceQueueCreateInfo - }; - - VkPhysicalDeviceFeatures physicalDeviceFeatures = {}; - const char *swapchainExtension = VK_KHR_SWAPCHAIN_EXTENSION_NAME; - const char **extensions = &swapchainExtension; - - VkDeviceCreateInfo deviceCreateInfo = {}; - deviceCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; - deviceCreateInfo.queueCreateInfoCount = 2; - deviceCreateInfo.pQueueCreateInfos = deviceQueueCreateInfos; - deviceCreateInfo.pEnabledFeatures = &physicalDeviceFeatures; - deviceCreateInfo.enabledExtensionCount = 1; - deviceCreateInfo.ppEnabledExtensionNames = extensions; - - ASSERT_VK(vkCreateDevice(compute->physicalDevice, &deviceCreateInfo, NULL, &(compute->device))) - - graphics->device = compute->device; - - vkGetDeviceQueue(compute->device, compute->queueFamilyIndex, 0, &(compute->queue)); - vkGetDeviceQueue(graphics->device, graphics->queueFamilyIndex, 0, &(graphics->queue)); -} - -uint32_t findMemoryType(Compute *compute, uint32_t memoryTypeBits, VkMemoryPropertyFlags properties) -{ - VkPhysicalDeviceMemoryProperties memoryProperties; - vkGetPhysicalDeviceMemoryProperties(compute->physicalDevice, &memoryProperties); - - for (uint32_t i = 0; i < memoryProperties.memoryTypeCount; i++) - { - if ((memoryTypeBits & (1u << i)) - && ((memoryProperties.memoryTypes[i].propertyFlags & properties) == properties)) - return i; - } - - return UINT32_MAX; -} - -void createParticleBuffer(Compute *compute, Graphics *graphics) -{ - uint32_t queueFamilyIndices[2] = { - compute->queueFamilyIndex, - graphics->queueFamilyIndex - }; - - VkBufferCreateInfo particleBufferCreateInfo = {}; - particleBufferCreateInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; - particleBufferCreateInfo.size = compute->particleBufferSize; - particleBufferCreateInfo.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; - particleBufferCreateInfo.sharingMode = VK_SHARING_MODE_CONCURRENT; - particleBufferCreateInfo.queueFamilyIndexCount = 2; - particleBufferCreateInfo.pQueueFamilyIndices = queueFamilyIndices; - - ASSERT_VK(vkCreateBuffer(compute->device, &particleBufferCreateInfo, NULL, &(compute->particleBuffer))) - - VkMemoryRequirements particleBufferMemoryRequirements; - vkGetBufferMemoryRequirements(compute->device, compute->particleBuffer, &particleBufferMemoryRequirements); - - VkMemoryAllocateInfo particleMemoryAllocateInfo = {}; - particleMemoryAllocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; - particleMemoryAllocateInfo.allocationSize = particleBufferMemoryRequirements.size; - particleMemoryAllocateInfo.memoryTypeIndex = findMemoryType(compute, - particleBufferMemoryRequirements.memoryTypeBits, - VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); - - ASSERT_VK(vkAllocateMemory(compute->device, &particleMemoryAllocateInfo, NULL, &(compute->particleBufferMemory))) - - ASSERT_VK(vkBindBufferMemory(compute->device, compute->particleBuffer, compute->particleBufferMemory, 0)) -} - -void createComputeBuffer(Compute *compute, uint32_t bufferSize, VkBufferUsageFlags usageFlags, VkBuffer *buffer, - VkDeviceMemory *bufferMemory, VkMemoryPropertyFlags memoryPropertyFlags) -{ - VkBufferCreateInfo bufferCreateInfo = {}; - bufferCreateInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; - bufferCreateInfo.size = bufferSize; - bufferCreateInfo.usage = usageFlags; - bufferCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; - - ASSERT_VK(vkCreateBuffer(compute->device, &bufferCreateInfo, NULL, buffer)) - - VkMemoryRequirements bufferMemoryRequirements; - vkGetBufferMemoryRequirements(compute->device, *buffer, &bufferMemoryRequirements); - - VkMemoryAllocateInfo memoryAllocateInfo = {}; - memoryAllocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; - memoryAllocateInfo.allocationSize = bufferMemoryRequirements.size; - memoryAllocateInfo.memoryTypeIndex = findMemoryType(compute, - bufferMemoryRequirements.memoryTypeBits, - memoryPropertyFlags); - - ASSERT_VK(vkAllocateMemory(compute->device, &memoryAllocateInfo, NULL, bufferMemory)) - - ASSERT_VK(vkBindBufferMemory(compute->device, *buffer, *bufferMemory, 0)) -} - -void createComputeBuffers(Compute *compute) -{ - // dt Uniform Buffer - createComputeBuffer(compute, compute->dtUniformBufferSize, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, - &(compute->dtUniformBuffer), - &(compute->dtUniformBufferMemory), - VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); - - // staticIn Uniform Buffer - createComputeBuffer(compute, compute->staticInUniformBufferSize, - VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, - &(compute->staticInUniformBuffer), - &(compute->staticInUniformBufferMemory), VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); - -} - -void createComputeDescriptorSetLayout(Compute *compute, VkDescriptorType descriptorType, VkDescriptorSetLayout *descriptorSetLayout) -{ - VkDescriptorSetLayoutBinding descriptorSetLayoutBinding = {}; - descriptorSetLayoutBinding.binding = 0; - descriptorSetLayoutBinding.descriptorType = descriptorType; - descriptorSetLayoutBinding.descriptorCount = 1; - descriptorSetLayoutBinding.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT; - - VkDescriptorSetLayoutCreateInfo descriptorSetLayoutCreateInfo = {}; - descriptorSetLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; - descriptorSetLayoutCreateInfo.bindingCount = 1; - descriptorSetLayoutCreateInfo.pBindings = &descriptorSetLayoutBinding; - - ASSERT_VK(vkCreateDescriptorSetLayout(compute->device, &descriptorSetLayoutCreateInfo, NULL, descriptorSetLayout)) -} - -void createComputeDescriptorSetLayouts(Compute *compute) -{ - // Particle Buffer - createComputeDescriptorSetLayout(compute, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, - &(compute->particleBufferDescriptorSetLayout)); - - // dt Uniform Buffer - createComputeDescriptorSetLayout(compute, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, - &(compute->dtUniformBufferDescriptorSetLayout)); - - // staticIn Uniform Buffer - createComputeDescriptorSetLayout(compute, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, - &(compute->staticInUniformBufferDescriptorSetLayout)); -} - -void createComputeDescriptorSet(Compute *compute, VkDescriptorType descriptorType, VkDescriptorPool *descriptorPool, - VkDescriptorSetLayout *descriptorSetLayout, VkDescriptorSet *descriptorSet, - VkBuffer buffer, uint32_t bufferSize) -{ - VkDescriptorPoolSize descriptorPoolSize = {}; - descriptorPoolSize.type = descriptorType; - descriptorPoolSize.descriptorCount = 1; - - VkDescriptorPoolCreateInfo descriptorPoolCreateInfo = {}; - descriptorPoolCreateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; - descriptorPoolCreateInfo.maxSets = 1; - descriptorPoolCreateInfo.poolSizeCount = 1; - descriptorPoolCreateInfo.pPoolSizes = &descriptorPoolSize; - - ASSERT_VK(vkCreateDescriptorPool(compute->device, &descriptorPoolCreateInfo, NULL, descriptorPool)) - - VkDescriptorSetAllocateInfo descriptorSetAllocateInfo = {}; - descriptorSetAllocateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; - descriptorSetAllocateInfo.descriptorPool = *descriptorPool; - descriptorSetAllocateInfo.descriptorSetCount = 1; - descriptorSetAllocateInfo.pSetLayouts = descriptorSetLayout; - - ASSERT_VK(vkAllocateDescriptorSets(compute->device, &descriptorSetAllocateInfo, descriptorSet)) - - VkDescriptorBufferInfo descriptorBufferInfo = {}; - descriptorBufferInfo.buffer = buffer; - descriptorBufferInfo.offset = 0; - descriptorBufferInfo.range = bufferSize; - - VkWriteDescriptorSet writeDescriptorSet = {}; - writeDescriptorSet.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - writeDescriptorSet.dstSet = *descriptorSet; - writeDescriptorSet.dstBinding = 0; - writeDescriptorSet.descriptorCount = 1; - writeDescriptorSet.descriptorType = descriptorType; - writeDescriptorSet.pBufferInfo = &descriptorBufferInfo; - - vkUpdateDescriptorSets(compute->device, 1, &writeDescriptorSet, 0, NULL); -} - -void createComputeDescriptorSets(Compute *compute) -{ - // Particle Buffer - createComputeDescriptorSet(compute, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &(compute->particleBufferDescriptorPool), - &(compute->particleBufferDescriptorSetLayout), &(compute->particleBufferDescriptorSet), - compute->particleBuffer, compute->particleBufferSize); - - // dt Uniform Buffer - createComputeDescriptorSet(compute, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, &(compute->dtUniformBufferDescriptorPool), - &(compute->dtUniformBufferDescriptorSetLayout), &(compute->dtUniformBufferDescriptorSet), - compute->dtUniformBuffer, compute->dtUniformBufferSize); - - // staticIn Uniform Buffer - createComputeDescriptorSet(compute, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, - &(compute->staticInUniformBufferDescriptorPool), - &(compute->staticInUniformBufferDescriptorSetLayout), - &(compute->staticInUniformBufferDescriptorSet), - compute->staticInUniformBuffer, compute->staticInUniformBufferSize); -} - -void createShaderModule(VkDevice device, char *filename, VkShaderModule *shaderModule) -{ - long shaderSourceSize; - char *shaderSource = readFile(filename, "rb", &shaderSourceSize); - - VkShaderModuleCreateInfo shaderModuleInfo; - shaderModuleInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; - shaderModuleInfo.pNext = NULL; - shaderModuleInfo.flags = 0; - shaderModuleInfo.codeSize = shaderSourceSize; - shaderModuleInfo.pCode = (uint32_t *) shaderSource; - - ASSERT_VK(vkCreateShaderModule(device, &shaderModuleInfo, NULL, shaderModule)) - - free(shaderSource); -} - -void createComputePipeline(Compute *compute) -{ - createShaderModule(compute->device, "./vulkan/comp.spv", &(compute->shaderModule)); - - VkPipelineShaderStageCreateInfo pipelineShaderStageCreateInfo = {}; - pipelineShaderStageCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; - pipelineShaderStageCreateInfo.stage = VK_SHADER_STAGE_COMPUTE_BIT; - pipelineShaderStageCreateInfo.module = compute->shaderModule; - pipelineShaderStageCreateInfo.pName = "main"; - - VkDescriptorSetLayout descriptorSetLayouts[] = { - compute->particleBufferDescriptorSetLayout, - compute->dtUniformBufferDescriptorSetLayout, - compute->staticInUniformBufferDescriptorSetLayout - }; - - VkPushConstantRange dtPushConstantRange = {}; - dtPushConstantRange.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT; - dtPushConstantRange.offset = 0; - dtPushConstantRange.size = sizeof(Dt); - - VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo = {}; - pipelineLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; - pipelineLayoutCreateInfo.setLayoutCount = 3; - pipelineLayoutCreateInfo.pSetLayouts = descriptorSetLayouts; - pipelineLayoutCreateInfo.pushConstantRangeCount = 1; - pipelineLayoutCreateInfo.pPushConstantRanges = &dtPushConstantRange; - - ASSERT_VK(vkCreatePipelineLayout(compute->device, &pipelineLayoutCreateInfo, NULL, &(compute->pipelineLayout))) - - VkComputePipelineCreateInfo pipelineCreateInfo = {}; - pipelineCreateInfo.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO; - pipelineCreateInfo.stage = pipelineShaderStageCreateInfo; - pipelineCreateInfo.layout = compute->pipelineLayout; - pipelineCreateInfo.basePipelineHandle = VK_NULL_HANDLE; - pipelineCreateInfo.basePipelineIndex = -1; - - ASSERT_VK(vkCreateComputePipelines(compute->device, VK_NULL_HANDLE, 1, &pipelineCreateInfo, NULL, &(compute->pipeline))) -} - -void mapBufferMemory(Compute *compute, VkDeviceMemory memory, void *inputData, uint32_t dataSize) -{ - void *vkData; - vkMapMemory(compute->device, memory, 0, dataSize, 0, &vkData); - memcpy(vkData, inputData, dataSize); - vkUnmapMemory(compute->device, memory); -} - -void copyBuffer(Compute *compute, VkBuffer src, VkBuffer dst, VkDeviceSize size) -{ - uint32_t queueFamilyIndex = getQueueFamilyIndex(compute->physicalDevice, VK_QUEUE_TRANSFER_BIT, 0); - - VkCommandPoolCreateInfo commandPoolCreateInfo = {}; - commandPoolCreateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; - commandPoolCreateInfo.flags = 0; - commandPoolCreateInfo.queueFamilyIndex = queueFamilyIndex; - - VkCommandPool stagingCommandPool; - ASSERT_VK(vkCreateCommandPool(compute->device, &commandPoolCreateInfo, NULL, &stagingCommandPool)) - - VkCommandBufferAllocateInfo allocInfo = {}; - allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; - allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; - allocInfo.commandPool = stagingCommandPool; - allocInfo.commandBufferCount = 1; - - VkCommandBuffer stagingCommandBuffer; - ASSERT_VK(vkAllocateCommandBuffers(compute->device, &allocInfo, &stagingCommandBuffer)) - - VkCommandBufferBeginInfo beginInfo = {}; - beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; - beginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; - - ASSERT_VK(vkBeginCommandBuffer(stagingCommandBuffer, &beginInfo)) - - VkBufferCopy copyRegion = { .size = size }; - vkCmdCopyBuffer(stagingCommandBuffer, src, dst, 1, ©Region); - - ASSERT_VK(vkEndCommandBuffer(stagingCommandBuffer)) - - VkSubmitInfo submitInfo = {}; - submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; - submitInfo.commandBufferCount = 1; - submitInfo.pCommandBuffers = &stagingCommandBuffer; - - VkQueue stagingQueue; - vkGetDeviceQueue(compute->device, queueFamilyIndex, 0, &stagingQueue); - - vkQueueSubmit(stagingQueue, 1, &submitInfo, VK_NULL_HANDLE); - vkQueueWaitIdle(stagingQueue); - - vkFreeCommandBuffers(compute->device, stagingCommandPool, 1, &stagingCommandBuffer); -} - -void fillComputeBuffer(Compute *compute, VkBuffer dst, void *data, uint32_t dataSize) -{ - VkBuffer stagingBuffer; - VkDeviceMemory stagingBuggerMemory; - createComputeBuffer(compute, compute->particleBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, &stagingBuffer, &stagingBuggerMemory, - VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); - - mapBufferMemory(compute, stagingBuggerMemory, data, dataSize); - - copyBuffer(compute, stagingBuffer, dst, dataSize); -} - -void fillComputeBuffers(Compute *compute, float *particles, Dt *dtData, StaticIn *staticInData) -{ - // Particle Buffer - fillComputeBuffer(compute, compute->particleBuffer, particles, compute->particleBufferSize); - - // dt Buffer - mapBufferMemory(compute, compute->dtUniformBufferMemory, dtData, compute->dtUniformBufferSize); - - // staticIn Buffer - fillComputeBuffer(compute, compute->staticInUniformBuffer, staticInData, compute->staticInUniformBufferSize); -} - -void createComputeCommandBuffer(Compute *compute) -{ - VkCommandPoolCreateInfo commandPoolCreateInfo = {}; - commandPoolCreateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; - commandPoolCreateInfo.flags = 0; - commandPoolCreateInfo.queueFamilyIndex = compute->queueFamilyIndex; - - ASSERT_VK(vkCreateCommandPool(compute->device, &commandPoolCreateInfo, NULL, &(compute->commandPool))) - - VkCommandBufferAllocateInfo commandBufferAllocateInfo = {}; - commandBufferAllocateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; - commandBufferAllocateInfo.commandPool = compute->commandPool; - commandBufferAllocateInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; - commandBufferAllocateInfo.commandBufferCount = 1; - - ASSERT_VK(vkAllocateCommandBuffers(compute->device, &commandBufferAllocateInfo, &(compute->commandBuffer))) - - VkCommandBufferBeginInfo beginInfo = {}; - beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; - beginInfo.flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT; - - ASSERT_VK(vkBeginCommandBuffer(compute->commandBuffer, &beginInfo)) - - vkCmdBindPipeline(compute->commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, compute->pipeline); - VkDescriptorSet descriptorSets[] = { - compute->particleBufferDescriptorSet, - compute->dtUniformBufferDescriptorSet, - compute->staticInUniformBufferDescriptorSet - }; - vkCmdBindDescriptorSets(compute->commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, compute->pipelineLayout, 0, 3, - descriptorSets, 0, NULL); - - vkCmdDispatch(compute->commandBuffer, WORKGROUP_SIZE_X, WORKGROUP_SIZE_Y, WORKGROUP_SIZE_Z); - - ASSERT_VK(vkEndCommandBuffer(compute->commandBuffer)) -} - -void createSemaphore(VkDevice device, VkSemaphore *semaphore) -{ - VkSemaphoreCreateInfo semaphoreCreateInfo = { .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO }; - ASSERT_VK(vkCreateSemaphore(device, &semaphoreCreateInfo, NULL, semaphore)); -} - -void shutdownComputeVulkan(Compute *compute) -{ - vkDeviceWaitIdle(compute->device); - - vkDestroySemaphore(compute->device, compute->semaphore, NULL); - - vkFreeMemory(compute->device, compute->particleBufferMemory, NULL); - vkFreeMemory(compute->device, compute->dtUniformBufferMemory, NULL); - vkFreeMemory(compute->device, compute->staticInUniformBufferMemory, NULL); - - vkDestroyBuffer(compute->device, compute->particleBuffer, NULL); - vkDestroyBuffer(compute->device, compute->dtUniformBuffer, NULL); - vkDestroyBuffer(compute->device, compute->staticInUniformBuffer, NULL); - - vkDestroyPipelineLayout(compute->device, compute->pipelineLayout, NULL); - - vkDestroyDescriptorPool(compute->device, compute->particleBufferDescriptorPool, NULL); - vkDestroyDescriptorPool(compute->device, compute->dtUniformBufferDescriptorPool, NULL); - vkDestroyDescriptorPool(compute->device, compute->staticInUniformBufferDescriptorPool, NULL); - - vkDestroyDescriptorSetLayout(compute->device, compute->particleBufferDescriptorSetLayout, NULL); - vkDestroyDescriptorSetLayout(compute->device, compute->dtUniformBufferDescriptorSetLayout, NULL); - vkDestroyDescriptorSetLayout(compute->device, compute->staticInUniformBufferDescriptorSetLayout, NULL); - - vkDestroyPipeline(compute->device, compute->pipeline, NULL); - - vkDestroyShaderModule(compute->device, compute->shaderModule, NULL); - - vkFreeCommandBuffers(compute->device, compute->commandPool, 1, &(compute->commandBuffer)); - - vkDestroyCommandPool(compute->device, compute->commandPool, NULL); - - vkDestroyDevice(compute->device, NULL); - - vkDestroyInstance(compute->instance, NULL); -} - -void createGraphicsSurface(Graphics *graphics, GLFWwindow *window) -{ - ASSERT_VK(glfwCreateWindowSurface(graphics->instance, window, NULL, &(graphics->surface))) -} - -void createSwapchain(Graphics *graphics) -{ - VkBool32 swapChainSupport; - ASSERT_VK(vkGetPhysicalDeviceSurfaceSupportKHR(graphics->physicalDevice, 0, graphics->surface, &swapChainSupport)) - if (!swapChainSupport) - { - printf("ERROR: Swap chain not supported!"); - assert(!swapChainSupport); - } - - VkExtent2D imageExtent = { WIDTH, HEIGHT }; - VkSwapchainCreateInfoKHR swapChainCreateInfo = {}; - swapChainCreateInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR; - swapChainCreateInfo.surface = graphics->surface; - swapChainCreateInfo.minImageCount = 1; - swapChainCreateInfo.imageFormat = VK_FORMAT_B8G8R8A8_UNORM; - swapChainCreateInfo.imageColorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR; - swapChainCreateInfo.imageExtent = imageExtent; - swapChainCreateInfo.imageArrayLayers = 1; - swapChainCreateInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; - swapChainCreateInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE; - swapChainCreateInfo.preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR; - swapChainCreateInfo.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; - swapChainCreateInfo.presentMode = VK_PRESENT_MODE_IMMEDIATE_KHR; - swapChainCreateInfo.clipped = VK_FALSE; - swapChainCreateInfo.oldSwapchain = VK_NULL_HANDLE; - - ASSERT_VK(vkCreateSwapchainKHR(graphics->device, &swapChainCreateInfo, NULL, &(graphics->swapChain))) - - vkGetSwapchainImagesKHR(graphics->device, graphics->swapChain, &(graphics->imageViewsSize), NULL); - VkImage swapChainImages[graphics->imageViewsSize]; - ASSERT_VK(vkGetSwapchainImagesKHR(graphics->device, graphics->swapChain, &(graphics->imageViewsSize), swapChainImages)) - - graphics->imageViews = malloc(graphics->imageViewsSize * sizeof(VkImageView)); - - for (int i = 0; i < graphics->imageViewsSize; i++) - { - VkImageViewCreateInfo imageViewInfo = {}; - VkComponentMapping componentMapping = { - VK_COMPONENT_SWIZZLE_IDENTITY, - VK_COMPONENT_SWIZZLE_IDENTITY, - VK_COMPONENT_SWIZZLE_IDENTITY, - VK_COMPONENT_SWIZZLE_IDENTITY - }; - VkImageSubresourceRange subresourceRange = { - VK_IMAGE_ASPECT_COLOR_BIT,0, 1, 0, 1 - }; - - imageViewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; - imageViewInfo.image = swapChainImages[i]; - imageViewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D; - imageViewInfo.format = VK_FORMAT_B8G8R8A8_UNORM; - imageViewInfo.components = componentMapping; - imageViewInfo.subresourceRange = subresourceRange; - - ASSERT_VK(vkCreateImageView(graphics->device, &imageViewInfo, NULL, &(graphics->imageViews[i]))) - } -} - -void createShaderStageInfo(VkPipelineShaderStageCreateInfo *shaderStageCreateInfo, VkShaderStageFlagBits shaderStageFlagBits, - VkShaderModule shaderModule) -{ - shaderStageCreateInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; - shaderStageCreateInfo->stage = shaderStageFlagBits; - shaderStageCreateInfo->module = shaderModule; - shaderStageCreateInfo->pName = "main"; -} - -void createGraphicsPipeline(Graphics *graphics) -{ - VkVertexInputBindingDescription vertexInputBindingDescription; - vertexInputBindingDescription.binding = 0; - vertexInputBindingDescription.stride = PARTICLE_SIZE; - vertexInputBindingDescription.inputRate = VK_VERTEX_INPUT_RATE_VERTEX; - - VkVertexInputAttributeDescription positionVertexInputAttributeDescription; - positionVertexInputAttributeDescription.binding = 0; - positionVertexInputAttributeDescription.location = 0; - positionVertexInputAttributeDescription.format = VK_FORMAT_R32G32B32_SFLOAT; - positionVertexInputAttributeDescription.offset = 0; - - VkVertexInputAttributeDescription colInVertexInputAttributeDescription; - colInVertexInputAttributeDescription.binding = 0; - colInVertexInputAttributeDescription.location = 1; - colInVertexInputAttributeDescription.format = VK_FORMAT_R32G32B32_SFLOAT; - colInVertexInputAttributeDescription.offset = 24; - - VkVertexInputAttributeDescription vertexInputAttributeDescription[2] = { - positionVertexInputAttributeDescription, - colInVertexInputAttributeDescription - }; - - VkPipelineVertexInputStateCreateInfo vertexInputStateInfo = {}; - vertexInputStateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; - vertexInputStateInfo.vertexBindingDescriptionCount = 1; - vertexInputStateInfo.pVertexBindingDescriptions = &vertexInputBindingDescription; - vertexInputStateInfo.vertexAttributeDescriptionCount = 2; - vertexInputStateInfo.pVertexAttributeDescriptions = vertexInputAttributeDescription; - - createShaderModule(graphics->device, "./vulkan/vert.spv", &(graphics->vertexShaderModule)); - createShaderModule(graphics->device, "./vulkan/frag.spv", &(graphics->fragmentShaderModule)); - - VkPipelineShaderStageCreateInfo vertexShaderStageInfo = {}; - createShaderStageInfo(&vertexShaderStageInfo, VK_SHADER_STAGE_VERTEX_BIT, graphics->vertexShaderModule); - VkPipelineShaderStageCreateInfo fragmentShaderStageInfo = {}; - createShaderStageInfo(&fragmentShaderStageInfo, VK_SHADER_STAGE_FRAGMENT_BIT, graphics->fragmentShaderModule); - - VkPipelineShaderStageCreateInfo shaderStages[] = { - vertexShaderStageInfo, - fragmentShaderStageInfo - }; - - VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateInfo = {}; - inputAssemblyStateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; - inputAssemblyStateInfo.topology = VK_PRIMITIVE_TOPOLOGY_POINT_LIST; - inputAssemblyStateInfo.primitiveRestartEnable = VK_FALSE; - - VkViewport viewport = {}; - viewport.x = 0.0f; - viewport.y = 0.0f; - viewport.width = WIDTH; - viewport.height = HEIGHT; - viewport.minDepth = 0.0f; - viewport.maxDepth = 1.0f; - - VkRect2D scissor = { {0, 0}, {WIDTH, HEIGHT} }; - - VkPipelineViewportStateCreateInfo viewportStateInfo = {}; - viewportStateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; - viewportStateInfo.viewportCount = 1; - viewportStateInfo.pViewports = &viewport; - viewportStateInfo.scissorCount = 1; - viewportStateInfo.pScissors = &scissor; - - VkPipelineRasterizationStateCreateInfo rasterizationStateInfo = {}; - rasterizationStateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; - rasterizationStateInfo.depthClampEnable = VK_FALSE; - rasterizationStateInfo.rasterizerDiscardEnable = VK_FALSE; - rasterizationStateInfo.polygonMode = VK_POLYGON_MODE_FILL; - rasterizationStateInfo.cullMode = VK_CULL_MODE_BACK_BIT; - rasterizationStateInfo.frontFace = VK_FRONT_FACE_CLOCKWISE; - rasterizationStateInfo.depthBiasEnable = VK_FALSE; - rasterizationStateInfo.depthBiasConstantFactor = 0.0f; - rasterizationStateInfo.depthBiasClamp = 0.0f; - rasterizationStateInfo.depthBiasSlopeFactor = 0.0f; - rasterizationStateInfo.lineWidth = 1.0f; - - VkPipelineMultisampleStateCreateInfo multisampleStateInfo = {}; - multisampleStateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; - multisampleStateInfo.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; - multisampleStateInfo.sampleShadingEnable = VK_FALSE; - multisampleStateInfo.minSampleShading = 1.0f; - multisampleStateInfo.alphaToCoverageEnable = VK_FALSE; - multisampleStateInfo.alphaToOneEnable = VK_FALSE; - - VkPipelineColorBlendAttachmentState colorBlendAttachmentState = {}; - colorBlendAttachmentState.blendEnable = VK_FALSE; - colorBlendAttachmentState.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA; - colorBlendAttachmentState.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; - colorBlendAttachmentState.colorBlendOp = VK_BLEND_OP_ADD; - colorBlendAttachmentState.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE; - colorBlendAttachmentState.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO; - colorBlendAttachmentState.alphaBlendOp = VK_BLEND_OP_ADD; - colorBlendAttachmentState.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; - - VkPipelineColorBlendStateCreateInfo colorBlendStateInfo = {}; - colorBlendStateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; - colorBlendStateInfo.logicOpEnable = VK_FALSE; - colorBlendStateInfo.logicOp = VK_LOGIC_OP_NO_OP; - colorBlendStateInfo.attachmentCount = 1; - colorBlendStateInfo.pAttachments = &colorBlendAttachmentState; - colorBlendStateInfo.blendConstants[0] = 0.0f; - colorBlendStateInfo.blendConstants[1] = 0.0f; - colorBlendStateInfo.blendConstants[2] = 0.0f; - colorBlendStateInfo.blendConstants[3] = 0.0f; - - VkPipelineLayoutCreateInfo layoutInfo = {}; - layoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; - - ASSERT_VK(vkCreatePipelineLayout(graphics->device, &layoutInfo, NULL, &(graphics->pipelineLayout))) - - VkAttachmentDescription attachmentDescription = {}; - attachmentDescription.format = VK_FORMAT_B8G8R8A8_UNORM; - attachmentDescription.samples = VK_SAMPLE_COUNT_1_BIT; - attachmentDescription.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; - attachmentDescription.storeOp = VK_ATTACHMENT_STORE_OP_STORE; - attachmentDescription.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - attachmentDescription.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; - attachmentDescription.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; - attachmentDescription.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; - - VkAttachmentReference attachmentReference = {}; - attachmentReference.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - - VkSubpassDescription subpassDescription = {}; - subpassDescription.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; - subpassDescription.colorAttachmentCount = 1; - subpassDescription.pColorAttachments = &attachmentReference; - - VkSubpassDependency subpassDependency = {}; - subpassDependency.srcSubpass = VK_SUBPASS_EXTERNAL; - subpassDependency.dstSubpass = 0; - subpassDependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; - subpassDependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; - subpassDependency.srcAccessMask = 0; - subpassDependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; - - VkRenderPassCreateInfo renderPassInfo = {}; - renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; - renderPassInfo.attachmentCount = 1; - renderPassInfo.pAttachments = &attachmentDescription; - renderPassInfo.subpassCount = 1; - renderPassInfo.pSubpasses = &subpassDescription; - renderPassInfo.dependencyCount = 1; - renderPassInfo.pDependencies = &subpassDependency; - - - ASSERT_VK(vkCreateRenderPass(graphics->device, &renderPassInfo, NULL, &(graphics->renderPass))) - - VkGraphicsPipelineCreateInfo graphicsPipelineInfo = {}; - graphicsPipelineInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; - graphicsPipelineInfo.stageCount = 2; - graphicsPipelineInfo.pStages = shaderStages; - graphicsPipelineInfo.pVertexInputState = &vertexInputStateInfo; - graphicsPipelineInfo.pInputAssemblyState = &inputAssemblyStateInfo; - graphicsPipelineInfo.pViewportState = &viewportStateInfo; - graphicsPipelineInfo.pRasterizationState = &rasterizationStateInfo; - graphicsPipelineInfo.pMultisampleState = &multisampleStateInfo; - graphicsPipelineInfo.pColorBlendState = &colorBlendStateInfo; - graphicsPipelineInfo.layout = graphics->pipelineLayout; - graphicsPipelineInfo.renderPass = graphics->renderPass; - graphicsPipelineInfo.basePipelineHandle = VK_NULL_HANDLE; - graphicsPipelineInfo.basePipelineIndex = -1; - - ASSERT_VK(vkCreateGraphicsPipelines(graphics->device, VK_NULL_HANDLE, 1, &graphicsPipelineInfo, NULL, &(graphics->pipeline))) -} - -void createFramebuffer(Graphics *graphics) -{ - graphics->framebuffers = malloc(graphics->imageViewsSize * sizeof(VkFramebuffer)); - for (int i = 0; i < graphics->imageViewsSize; ++i) - { - VkFramebufferCreateInfo framebufferInfo = {}; - framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; - framebufferInfo.renderPass = graphics->renderPass; - framebufferInfo.attachmentCount = 1; - framebufferInfo.pAttachments = &(graphics->imageViews[i]); - framebufferInfo.width = WIDTH; - framebufferInfo.height = HEIGHT; - framebufferInfo.layers = 1; - - ASSERT_VK(vkCreateFramebuffer(graphics->device, &framebufferInfo, NULL, &(graphics->framebuffers[i]))) - } -} - -void createGraphicsCommandBuffers(Graphics *graphics) -{ - VkCommandPoolCreateInfo commandPoolInfo = {}; - commandPoolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; - commandPoolInfo.queueFamilyIndex = graphics->queueFamilyIndex; - - ASSERT_VK(vkCreateCommandPool(graphics->device, &commandPoolInfo, NULL, &(graphics->commandPool))) - - VkCommandBufferAllocateInfo commandBufferAllocateInfo = {}; - commandBufferAllocateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; - commandBufferAllocateInfo.commandPool = graphics->commandPool; - commandBufferAllocateInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; - commandBufferAllocateInfo.commandBufferCount = graphics->imageViewsSize; - - graphics->commandBuffers = malloc(graphics->imageViewsSize * sizeof(VkCommandBuffer)); - - ASSERT_VK(vkAllocateCommandBuffers(graphics->device, &commandBufferAllocateInfo, graphics->commandBuffers)) - - VkCommandBufferBeginInfo commandBufferBeginInfo = {}; - commandBufferBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; - commandBufferBeginInfo.flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT; - - VkRect2D renderArea = { {0, 0}, {WIDTH, HEIGHT} }; - VkClearValue clearValue = {0, 0, 0, 1}; - - for (int i = 0; i < graphics->imageViewsSize; i++) - { - ASSERT_VK(vkBeginCommandBuffer(graphics->commandBuffers[i], &commandBufferBeginInfo)) - - VkRenderPassBeginInfo renderPassBeginInfo = {}; - renderPassBeginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; - renderPassBeginInfo.renderPass = graphics->renderPass; - renderPassBeginInfo.framebuffer = graphics->framebuffers[i]; - renderPassBeginInfo.renderArea = renderArea; - renderPassBeginInfo.clearValueCount = 1; - renderPassBeginInfo.pClearValues = &clearValue; - - vkCmdBeginRenderPass(graphics->commandBuffers[i], &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); - - vkCmdBindPipeline(graphics->commandBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, graphics->pipeline); - - VkDeviceSize offsets[1] = { 0 }; - vkCmdBindVertexBuffers(graphics->commandBuffers[i], 0, 1, &(graphics->particleBuffer), offsets); - - vkCmdDraw(graphics->commandBuffers[i], PARTICLE_AMOUNT, 1, 0, 0); - - vkCmdEndRenderPass(graphics->commandBuffers[i]); - - ASSERT_VK(vkEndCommandBuffer(graphics->commandBuffers[i])) - } -} - -void shutdownGraphicsVulkan(Graphics *graphics) -{ - vkDeviceWaitIdle(graphics->device); - - for (int i = 0; i < graphics->imageViewsSize; ++i) - { - vkDestroyFramebuffer(graphics->device, graphics->framebuffers[i], NULL); - } - - vkDestroyCommandPool(graphics->device, graphics->commandPool, NULL); - - vkDestroySemaphore(graphics->device, graphics->semaphore, NULL); - vkDestroySemaphore(graphics->device, graphics->renderComplete, NULL); - vkDestroySemaphore(graphics->device, graphics->presentComplete, NULL); - - vkDestroyPipelineLayout(graphics->device, graphics->pipelineLayout, NULL); - - vkDestroyRenderPass(graphics->device, graphics->renderPass, NULL); - - vkDestroyPipeline(graphics->device, graphics->pipeline, NULL); - - vkDestroyShaderModule(graphics->device, graphics->fragmentShaderModule, NULL); - vkDestroyShaderModule(graphics->device, graphics->vertexShaderModule, NULL); - - for (int i = 0; i < graphics->imageViewsSize; ++i) - { - vkDestroyImageView(graphics->device, graphics->imageViews[i], NULL); - } - - vkDestroySwapchainKHR(graphics->device, graphics->swapChain, NULL); - - vkDestroySurfaceKHR(graphics->instance, graphics->surface, NULL); -} \ No newline at end of file diff --git a/newVulkan/initVulkan.h b/newVulkan/initVulkan.h deleted file mode 100644 index f1455b4..0000000 --- a/newVulkan/initVulkan.h +++ /dev/null @@ -1,147 +0,0 @@ -#include -#include -#include -#include "vulkan/vulkan.h" - -#define GLFW_INCLUDE_VULKAN -#include "GLFW/glfw3.h" - -#include "../particlesystem.h" -#include "../utils.h" - -#define APP_NAME "Informatikprojekt - Vulkan" -#define APP_VERSION VK_MAKE_VERSION(0, 0, 0) -#define ENGINE_NAME "rwu_particles" -#define ENGINE_VERSION VK_MAKE_VERSION(0, 0, 0) - -#define PARTICLE_AMOUNT 1000000 -#define PARTICLE_SIZE (3 * sizeof(vector3f) + sizeof(float)) -#define WORKGROUP_SIZE_X 1024 -#define WORKGROUP_SIZE_Y 1 -#define WORKGROUP_SIZE_Z 1 - -#define SUCCESS 0 -#define FAILURE -1 -#define ASSERT_VK(f) { \ - VkResult res = (f); \ - if (res != VK_SUCCESS) { \ - printf("Fatal : VkResult is %d in %s at line %d\n", res, __FILE__, __LINE__); \ - assert(res == VK_SUCCESS); \ - } \ -} -#define ASSERT_GLFW_SUCCESS(res) { if (res != GLFW_TRUE) { printf("Error-Code: %d", res); return FAILURE; } } - -typedef struct dt { - float dt; -} Dt; - -typedef struct staticIn { - float x; - float y; - float z; - unsigned int maxParticles; -} StaticIn; - -typedef struct compute { - VkInstance instance; - - VkPhysicalDevice physicalDevice; - VkDevice device; - - VkPipeline pipeline; - VkPipelineLayout pipelineLayout; - VkShaderModule shaderModule; - - VkCommandPool commandPool; - VkCommandBuffer commandBuffer; - - VkDescriptorSetLayout particleBufferDescriptorSetLayout; - VkDescriptorPool particleBufferDescriptorPool; - VkDescriptorSet particleBufferDescriptorSet; - VkBuffer particleBuffer; - VkDeviceMemory particleBufferMemory; - uint32_t particleBufferSize; - - VkDescriptorSetLayout dtUniformBufferDescriptorSetLayout; - VkDescriptorPool dtUniformBufferDescriptorPool; - VkDescriptorSet dtUniformBufferDescriptorSet; - VkBuffer dtUniformBuffer; - VkDeviceMemory dtUniformBufferMemory; - uint32_t dtUniformBufferSize; - - VkDescriptorSetLayout staticInUniformBufferDescriptorSetLayout; - VkDescriptorPool staticInUniformBufferDescriptorPool; - VkDescriptorSet staticInUniformBufferDescriptorSet; - VkBuffer staticInUniformBuffer; - VkDeviceMemory staticInUniformBufferMemory; - uint32_t staticInUniformBufferSize; - - VkQueue queue; - uint32_t queueFamilyIndex; - - VkSemaphore semaphore; -} Compute; - -typedef struct graphics { - VkInstance instance; - - VkPhysicalDevice physicalDevice; - VkDevice device; - - VkSurfaceKHR surface; - VkSwapchainKHR swapChain; - - VkImageView *imageViews; - uint32_t imageViewsSize; - - VkRenderPass renderPass; - VkFramebuffer *framebuffers; - - VkPipeline pipeline; - VkPipelineLayout pipelineLayout; - VkShaderModule vertexShaderModule; - VkShaderModule fragmentShaderModule; - - VkCommandPool commandPool; - VkCommandBuffer *commandBuffers; - - VkBuffer particleBuffer; - uint32_t particleBufferSize; - - VkQueue queue; - uint32_t queueFamilyIndex; - - VkSemaphore renderComplete; - VkSemaphore presentComplete; - VkSemaphore semaphore; -} Graphics; - -// Shutdown -void shutdownGLFW(GLFWwindow *window); -void shutdownComputeVulkan(Compute *compute); -void shutdownGraphicsVulkan(Graphics *graphics); - -// General -void createInstance(Compute *compute, Graphics *graphics); -void findPhysicalDevice(Compute *compute, Graphics *graphics); -void createDevice(Compute *compute, Graphics *graphics); -void createParticleBuffer(Compute *compute, Graphics *graphics); - -// Compute -void createComputeBuffers(Compute *compute); -void createComputeDescriptorSetLayouts(Compute *compute); -void createComputeDescriptorSets(Compute *compute); -void createComputePipeline(Compute *compute); -void fillComputeBuffers(Compute *compute, float *particles, Dt *dtData, StaticIn *staticInData); -void createComputeCommandBuffer(Compute *compute); - -// Graphics -void createGraphicsSurface(Graphics *graphics, GLFWwindow *window); -void createSwapchain(Graphics *graphics); -void createGraphicsPipeline(Graphics *graphics); -void createFramebuffer(Graphics *graphics); -void createGraphicsCommandBuffers(Graphics *graphics); - -// ELse -void mapBufferMemory(Compute *compute, VkDeviceMemory memory, void *inputData, uint32_t dataSize); -void createSemaphore(VkDevice device, VkSemaphore *semaphore); diff --git a/newVulkan/vulkanMain.c b/newVulkan/vulkanMain.c deleted file mode 100644 index 88cd1f3..0000000 --- a/newVulkan/vulkanMain.c +++ /dev/null @@ -1,146 +0,0 @@ -#include - -#include "initVulkan.h" - -int main() -{ - /************* PARTICLE SYSTEM *************/ - vector3f *epos1 = initVector3f(0, 0, 0); - emitter *e1 = initEmitter(epos1, PARTICLE_AMOUNT); - particle_system *ps = initParticleSystem(1); - (ps->emitters)[0] = e1; - initRandomParticles(e1); - float *particles = serializeParticlesystem(ps); - - Dt dt = { 0.5f }; - StaticIn staticIn = { - e1->position->x, - e1->position->y, - e1->position->z, - PARTICLE_AMOUNT - }; - - freeParticleSystem(ps); - - /************* INIT GLFW *************/ - ASSERT_GLFW_SUCCESS(glfwInit()); - glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); - glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE); - GLFWwindow *window = glfwCreateWindow(WIDTH, HEIGHT, "Informatikprojekt - Vulkan", NULL, NULL); - - /************* INIT VULKAN *************/ - Compute compute = { - .particleBufferSize = PARTICLE_SIZE * PARTICLE_AMOUNT, - .staticInUniformBufferSize = sizeof(StaticIn), - .dtUniformBufferSize = sizeof(Dt) - }; - Graphics graphics = {}; - - // General - createInstance(&compute, &graphics); - findPhysicalDevice(&compute, &graphics); - createDevice(&compute, &graphics); - createParticleBuffer(&compute, &graphics); - - // Compute - createComputeBuffers(&compute); - createComputeDescriptorSetLayouts(&compute); - createComputeDescriptorSets(&compute); - createComputePipeline(&compute); - fillComputeBuffers(&compute, particles, &dt, &staticIn); - - createSemaphore(compute.device, &(compute.semaphore)); - VkSubmitInfo submitInfo = {}; - submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; - submitInfo.signalSemaphoreCount = 1; - submitInfo.pSignalSemaphores = &compute.semaphore; - ASSERT_VK(vkQueueSubmit(compute.queue, 1, &submitInfo, VK_NULL_HANDLE)); - ASSERT_VK(vkQueueWaitIdle(compute.queue)); - - createComputeCommandBuffer(&compute); - - // Graphics - graphics.particleBuffer = compute.particleBuffer; - graphics.particleBufferSize = compute.particleBufferSize; - createGraphicsSurface(&graphics, window); - createSwapchain(&graphics); - createGraphicsPipeline(&graphics); - createFramebuffer(&graphics); - createGraphicsCommandBuffers(&graphics); - createSemaphore(graphics.device, &(graphics.presentComplete)); - createSemaphore(graphics.device, &(graphics.renderComplete)); - createSemaphore(graphics.device, &(graphics.semaphore)); - - /************* RENDER LOOP *************/ - // Graphics preparation - VkPipelineStageFlags graphicsWaitStageMasks[] = { - VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, - VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT - }; - VkSemaphore graphicsWaitSemaphores[] = { compute.semaphore, graphics.presentComplete }; - VkSemaphore graphicsSignalSemaphores[] = { graphics.semaphore, graphics.renderComplete }; - - VkSubmitInfo graphicsSubmitInfo = {}; - graphicsSubmitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; - graphicsSubmitInfo.commandBufferCount = 1; - graphicsSubmitInfo.waitSemaphoreCount = 2; - graphicsSubmitInfo.pWaitSemaphores = graphicsWaitSemaphores; - graphicsSubmitInfo.pWaitDstStageMask = graphicsWaitStageMasks; - graphicsSubmitInfo.signalSemaphoreCount = 2; - graphicsSubmitInfo.pSignalSemaphores = graphicsSignalSemaphores; - - VkPresentInfoKHR graphicsPresentInfo = {}; - graphicsPresentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; - graphicsPresentInfo.waitSemaphoreCount = 1; - graphicsPresentInfo.pWaitSemaphores = &(graphics.renderComplete); - graphicsPresentInfo.swapchainCount = 1; - graphicsPresentInfo.pSwapchains = &(graphics.swapChain); - - - // Compute preparation - VkPipelineStageFlags computeWaitStageMask = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; - - VkSubmitInfo computeSubmitInfo = {}; - computeSubmitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; - computeSubmitInfo.commandBufferCount = 1; - computeSubmitInfo.pCommandBuffers = &(compute.commandBuffer); - computeSubmitInfo.waitSemaphoreCount = 1; - computeSubmitInfo.pWaitSemaphores = &graphics.semaphore; - computeSubmitInfo.pWaitDstStageMask = &computeWaitStageMask; - computeSubmitInfo.signalSemaphoreCount = 1; - computeSubmitInfo.pSignalSemaphores = &compute.semaphore; - - // Loop - double time, tLast = 0; - Dt tFrame = {}; - uint32_t imageIndex; - while (!glfwWindowShouldClose(window)) - { - time = glfwGetTime(); - tFrame.dt = (float) (time - tLast); - tLast = time; - - /*** RENDER ***/ - ASSERT_VK(vkAcquireNextImageKHR(graphics.device, graphics.swapChain, UINT64_MAX, graphics.presentComplete, VK_NULL_HANDLE, &imageIndex)) - - graphicsSubmitInfo.pCommandBuffers = &(graphics.commandBuffers[imageIndex]); - ASSERT_VK(vkQueueSubmit(graphics.queue, 1, &graphicsSubmitInfo, VK_NULL_HANDLE)) - - graphicsPresentInfo.pImageIndices = &imageIndex; - ASSERT_VK(vkQueuePresentKHR(graphics.queue, &graphicsPresentInfo)) - - /*** UPDATE ***/ - // Update dt - mapBufferMemory(&compute, compute.dtUniformBufferMemory, &tFrame, sizeof(Dt)); - ASSERT_VK(vkQueueSubmit(compute.queue, 1, &computeSubmitInfo, VK_NULL_HANDLE)) - - glfwPollEvents(); - } - - shutdownGraphicsVulkan(&graphics); - shutdownComputeVulkan(&compute); - shutdownGLFW(window); - - return SUCCESS; -} - diff --git a/vulkanMain.c b/vulkanMain.c index 5102ebe..88cd1f3 100644 --- a/vulkanMain.c +++ b/vulkanMain.c @@ -1,232 +1,146 @@ #include #include "initVulkan.h" -#include "particlesystem.h" - -#define PARTICLE_AMOUNT 0 - -void drawFrame(); - -typedef struct compute { - VkInstance instance; - VkDebugReportCallbackEXT debugReportCallback; - - VkPhysicalDevice physicalDevice; - VkDevice device; - - VkPipeline pipeline; - VkPipelineLayout pipelineLayout; - VkShaderModule shaderModule; - - VkCommandPool commandPool; - VkCommandBuffer commandBuffer; - - VkDescriptorPool descriptorPool; - VkDescriptorSet descriptorSet; - VkDescriptorSetLayout descriptorSetLayout; - - VkBuffer buffer; - VkDeviceMemory bufferMemory; - uint32_t bufferSize; - - const char **enabledLayer; - - VkQueue queue; - uint32_t queueFamilyIndex; -} Compute; - int main() { - VkInstance vkInstance; - VkDevice device; - VkSurfaceKHR surface; - VkSwapchainKHR swapChain; - VkImageView *imageViews = NULL; - uint32_t imageViewsSize; - VkPipelineLayout pipelineLayout; - VkRenderPass renderPass; - VkPipeline pipeline; - VkFramebuffer *framebuffers; - VkCommandPool commandPool; - VkCommandBuffer *commandBuffers; - VkSemaphore imageAvailable; - VkSemaphore renderingFinished; - - /************* INIT *************/ - // GLFW - ASSERT_GLFW_SUCCESS(glfwInit()) - glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); - glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE); - GLFWwindow *window = glfwCreateWindow(WIDTH, HEIGHT, "Informatikprojekt - Vulkan", NULL, NULL); - - // Init Vulkan - ASSERT_SUCCESS(initVulkan(&vkInstance, &device, &surface, window, &swapChain, &imageViews, &imageViewsSize)) - /************* PARTICLE SYSTEM *************/ vector3f *epos1 = initVector3f(0, 0, 0); emitter *e1 = initEmitter(epos1, PARTICLE_AMOUNT); particle_system *ps = initParticleSystem(1); (ps->emitters)[0] = e1; initRandomParticles(e1); + float *particles = serializeParticlesystem(ps); - /************* SHADER *************/ - // Shader Modules - long computeShaderSourceSize, vertexShaderSourceSize, fragmentShaderSourceSize; - char *computeShaderSource = readFile("./vulkan/comp.spv", "rb", &computeShaderSourceSize); - char *vertexShaderSource = readFile("./vulkan/vert.spv", "rb", &vertexShaderSourceSize); - char *fragmentShaderSource = readFile("./vulkan/frag.spv", "rb", &fragmentShaderSourceSize); + Dt dt = { 0.5f }; + StaticIn staticIn = { + e1->position->x, + e1->position->y, + e1->position->z, + PARTICLE_AMOUNT + }; - VkShaderModule computeShaderModule; - createShaderModule(device, &computeShaderModule, computeShaderSource, computeShaderSourceSize); - VkShaderModule vertexShaderModule; - createShaderModule(device, &vertexShaderModule, vertexShaderSource, vertexShaderSourceSize); - VkShaderModule fragmentShaderModule; - createShaderModule(device, &fragmentShaderModule, fragmentShaderSource, fragmentShaderSourceSize); + freeParticleSystem(ps); - // Shader stages - VkPipelineShaderStageCreateInfo computeShaderStageInfo; - createShaderStageInfo(&computeShaderStageInfo, VK_SHADER_STAGE_COMPUTE_BIT, computeShaderModule, "main"); - VkPipelineShaderStageCreateInfo vertexShaderStageInfo; - createShaderStageInfo(&vertexShaderStageInfo, VK_SHADER_STAGE_VERTEX_BIT, vertexShaderModule, "main"); - VkPipelineShaderStageCreateInfo fragmentShaderStageInfo; - createShaderStageInfo(&fragmentShaderStageInfo, VK_SHADER_STAGE_FRAGMENT_BIT, fragmentShaderModule, "main"); + /************* INIT GLFW *************/ + ASSERT_GLFW_SUCCESS(glfwInit()); + glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); + glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE); + GLFWwindow *window = glfwCreateWindow(WIDTH, HEIGHT, "Informatikprojekt - Vulkan", NULL, NULL); - VkPipelineShaderStageCreateInfo shaderStages[3] = {computeShaderStageInfo, vertexShaderStageInfo, - fragmentShaderStageInfo}; + /************* INIT VULKAN *************/ + Compute compute = { + .particleBufferSize = PARTICLE_SIZE * PARTICLE_AMOUNT, + .staticInUniformBufferSize = sizeof(StaticIn), + .dtUniformBufferSize = sizeof(Dt) + }; + Graphics graphics = {}; - /************* PIPELINE *************/ - // Vertex input - VkPipelineVertexInputStateCreateInfo vertexInputStateInfo; - createPipelineVertexInputStateInfo(&vertexInputStateInfo, NULL, 0); + // General + createInstance(&compute, &graphics); + findPhysicalDevice(&compute, &graphics); + createDevice(&compute, &graphics); + createParticleBuffer(&compute, &graphics); - // Input assembly - VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateInfo; - createInputAssemblyStateInfo(&inputAssemblyStateInfo, VK_PRIMITIVE_TOPOLOGY_POINT_LIST); + // Compute + createComputeBuffers(&compute); + createComputeDescriptorSetLayouts(&compute); + createComputeDescriptorSets(&compute); + createComputePipeline(&compute); + fillComputeBuffers(&compute, particles, &dt, &staticIn); - // Viewport - VkPipelineViewportStateCreateInfo viewportStateInfo; - createViewportStateInfo(&viewportStateInfo, WIDTH, HEIGHT); + createSemaphore(compute.device, &(compute.semaphore)); + VkSubmitInfo submitInfo = {}; + submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; + submitInfo.signalSemaphoreCount = 1; + submitInfo.pSignalSemaphores = &compute.semaphore; + ASSERT_VK(vkQueueSubmit(compute.queue, 1, &submitInfo, VK_NULL_HANDLE)); + ASSERT_VK(vkQueueWaitIdle(compute.queue)); - // Rasterization - VkPipelineRasterizationStateCreateInfo rasterizationStateInfo; - createRasterizationStateInfo(&rasterizationStateInfo, VK_POLYGON_MODE_POINT); + createComputeCommandBuffer(&compute); - // Multisampling - VkPipelineMultisampleStateCreateInfo multisampleStateInfo; - createMultisampleStateInfo(&multisampleStateInfo); - - // Blending - VkPipelineColorBlendAttachmentState colorBlendAttachmentState; - createColorBlendAttachmentStateInfo(&colorBlendAttachmentState); - VkPipelineColorBlendStateCreateInfo colorBlendStateInfo; - createColorBlendStateInfo(&colorBlendStateInfo, &colorBlendAttachmentState, 1); - - // Layout - VkPipelineLayoutCreateInfo layoutInfo; - createLayoutInfo(&layoutInfo, NULL, 0); - ASSERT_VK_SUCCESS(vkCreatePipelineLayout(device, &layoutInfo, NULL, &pipelineLayout)) - - // Attachments - VkAttachmentDescription attachmentDescription; - createAttachmentDescription(&attachmentDescription); - - VkAttachmentReference attachmentReference; - createAttachmentReference(&attachmentReference, 0); - - // Subpasses - VkSubpassDescription subpassDescription; - createSubpassDescription(&subpassDescription, VK_PIPELINE_BIND_POINT_GRAPHICS, &attachmentReference); - - // Renderpass - VkRenderPassCreateInfo renderPassInfo; - createRenderPassInfo(&renderPassInfo, &attachmentDescription, &subpassDescription); - ASSERT_VK_SUCCESS(vkCreateRenderPass(device, &renderPassInfo, NULL, &renderPass)) - - // Graphics pipeline - VkGraphicsPipelineCreateInfo graphicsPipelineInfo; - createGraphicsPipelineInfo(&graphicsPipelineInfo, shaderStages, &vertexInputStateInfo, &inputAssemblyStateInfo, - &viewportStateInfo, &rasterizationStateInfo, &multisampleStateInfo, &colorBlendStateInfo, - &pipelineLayout, &renderPass); - ASSERT_VK_SUCCESS(vkCreateGraphicsPipelines(device, VK_NULL_HANDLE, 1, &graphicsPipelineInfo, NULL, &pipeline)) - - // Framebuffers - framebuffers = malloc(imageViewsSize * sizeof(VkFramebuffer)); - for (int i = 0; i < imageViewsSize; ++i) - { - VkFramebufferCreateInfo framebufferInfo; - createFramebufferInfo(&framebufferInfo, &renderPass, &imageViews[i]); - - ASSERT_VK_SUCCESS(vkCreateFramebuffer(device, &framebufferInfo, NULL, &framebuffers[i])) - } - - // Command pool - VkCommandPoolCreateInfo commandPoolInfo; - createCommandPoolInfo(&commandPoolInfo, 0); - ASSERT_VK_SUCCESS(vkCreateCommandPool(device, &commandPoolInfo, NULL, &commandPool)) - - // Allocate info - VkCommandBufferAllocateInfo commandBufferAllocateInfo; - createCommandBufferAllocateInfo(&commandBufferAllocateInfo, &commandPool, imageViewsSize); - - // Command buffers - commandBuffers = malloc(imageViewsSize * sizeof(VkCommandBuffer)); - ASSERT_VK_SUCCESS(vkAllocateCommandBuffers(device, &commandBufferAllocateInfo, commandBuffers)) - - // Begin Info command buffers - VkCommandBufferBeginInfo commandBufferBeginInfo; - createCommandBufferBeginInfo(&commandBufferBeginInfo); - - for (int i = 0; i < imageViewsSize; ++i) - { - ASSERT_VK_SUCCESS(vkBeginCommandBuffer(commandBuffers[i], &commandBufferBeginInfo)) - - VkRenderPassBeginInfo renderPassBeginInfo; - createRenderPassBeginInfo(&renderPassBeginInfo, &renderPass, &framebuffers[i]); - - vkCmdBeginRenderPass(commandBuffers[i], &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); - - vkCmdBindPipeline(commandBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline); - - vkCmdDraw(commandBuffers[i], 3, 1, 0, 0); - - vkCmdEndRenderPass(commandBuffers[i]); - - ASSERT_VK_SUCCESS(vkEndCommandBuffer(commandBuffers[i])) - } - - // Semaphores - VkSemaphoreCreateInfo semaphoreInfo; - createSemaphoreInfo(&semaphoreInfo); - - ASSERT_VK_SUCCESS(vkCreateSemaphore(device, &semaphoreInfo, NULL, &imageAvailable)) - ASSERT_VK_SUCCESS(vkCreateSemaphore(device, &semaphoreInfo, NULL, &renderingFinished)) + // Graphics + graphics.particleBuffer = compute.particleBuffer; + graphics.particleBufferSize = compute.particleBufferSize; + createGraphicsSurface(&graphics, window); + createSwapchain(&graphics); + createGraphicsPipeline(&graphics); + createFramebuffer(&graphics); + createGraphicsCommandBuffers(&graphics); + createSemaphore(graphics.device, &(graphics.presentComplete)); + createSemaphore(graphics.device, &(graphics.renderComplete)); + createSemaphore(graphics.device, &(graphics.semaphore)); /************* RENDER LOOP *************/ + // Graphics preparation + VkPipelineStageFlags graphicsWaitStageMasks[] = { + VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT + }; + VkSemaphore graphicsWaitSemaphores[] = { compute.semaphore, graphics.presentComplete }; + VkSemaphore graphicsSignalSemaphores[] = { graphics.semaphore, graphics.renderComplete }; + + VkSubmitInfo graphicsSubmitInfo = {}; + graphicsSubmitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; + graphicsSubmitInfo.commandBufferCount = 1; + graphicsSubmitInfo.waitSemaphoreCount = 2; + graphicsSubmitInfo.pWaitSemaphores = graphicsWaitSemaphores; + graphicsSubmitInfo.pWaitDstStageMask = graphicsWaitStageMasks; + graphicsSubmitInfo.signalSemaphoreCount = 2; + graphicsSubmitInfo.pSignalSemaphores = graphicsSignalSemaphores; + + VkPresentInfoKHR graphicsPresentInfo = {}; + graphicsPresentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; + graphicsPresentInfo.waitSemaphoreCount = 1; + graphicsPresentInfo.pWaitSemaphores = &(graphics.renderComplete); + graphicsPresentInfo.swapchainCount = 1; + graphicsPresentInfo.pSwapchains = &(graphics.swapChain); + + + // Compute preparation + VkPipelineStageFlags computeWaitStageMask = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; + + VkSubmitInfo computeSubmitInfo = {}; + computeSubmitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; + computeSubmitInfo.commandBufferCount = 1; + computeSubmitInfo.pCommandBuffers = &(compute.commandBuffer); + computeSubmitInfo.waitSemaphoreCount = 1; + computeSubmitInfo.pWaitSemaphores = &graphics.semaphore; + computeSubmitInfo.pWaitDstStageMask = &computeWaitStageMask; + computeSubmitInfo.signalSemaphoreCount = 1; + computeSubmitInfo.pSignalSemaphores = &compute.semaphore; + + // Loop + double time, tLast = 0; + Dt tFrame = {}; + uint32_t imageIndex; while (!glfwWindowShouldClose(window)) { + time = glfwGetTime(); + tFrame.dt = (float) (time - tLast); + tLast = time; + + /*** RENDER ***/ + ASSERT_VK(vkAcquireNextImageKHR(graphics.device, graphics.swapChain, UINT64_MAX, graphics.presentComplete, VK_NULL_HANDLE, &imageIndex)) + + graphicsSubmitInfo.pCommandBuffers = &(graphics.commandBuffers[imageIndex]); + ASSERT_VK(vkQueueSubmit(graphics.queue, 1, &graphicsSubmitInfo, VK_NULL_HANDLE)) + + graphicsPresentInfo.pImageIndices = &imageIndex; + ASSERT_VK(vkQueuePresentKHR(graphics.queue, &graphicsPresentInfo)) + + /*** UPDATE ***/ + // Update dt + mapBufferMemory(&compute, compute.dtUniformBufferMemory, &tFrame, sizeof(Dt)); + ASSERT_VK(vkQueueSubmit(compute.queue, 1, &computeSubmitInfo, VK_NULL_HANDLE)) + glfwPollEvents(); - drawFrame(); } - // Shutdown Vulkan - VkShaderModule modules[3] = {computeShaderModule, vertexShaderModule, fragmentShaderModule}; - VkSemaphore semaphores[2] = {imageAvailable, renderingFinished}; - shutdownVulkan(&vkInstance, &device, &surface, &swapChain, imageViews, imageViewsSize, modules, 3, &pipelineLayout, - 1, - &renderPass, 1, &pipeline, 1, framebuffers, &commandPool, commandBuffers, semaphores, 2); - - // Shutdown GLFW + shutdownGraphicsVulkan(&graphics); + shutdownComputeVulkan(&compute); shutdownGLFW(window); return SUCCESS; } -void drawFrame(VkDevice *device, VkSwapchainKHR *swapchainKhr, VkSemaphore *imageAvailable, VkSemaphore *renderingFinished) -{ - uint32_t imageIndex; - vkAcquireNextImageKHR(*device, *swapchainKhr, UINT64_MAX, *imageAvailable, VK_NULL_HANDLE, &imageIndex); -} - - -