1
0
rwu_particles_informatikpro.../initVulkan.c

896 lines
40 KiB
C
Raw Normal View History

2020-03-16 20:21:04 +00:00
#include "initVulkan.h"
2020-03-31 13:22:15 +00:00
#include <string.h>
2020-03-16 20:21:04 +00:00
2020-03-31 13:22:15 +00:00
void shutdownGLFW(GLFWwindow *window)
2020-03-16 20:21:04 +00:00
{
2020-03-31 13:22:15 +00:00
glfwDestroyWindow(window);
glfwTerminate();
}
2020-03-16 20:21:04 +00:00
2020-03-31 13:22:15 +00:00
void createInstance(Compute *compute, Graphics *graphics)
{
GLuint enabledLayerSize = 0;
2020-03-31 16:38:58 +00:00
const char **enabledLayer = NULL;
2020-03-31 13:22:15 +00:00
GLuint extensionsSize;
const char **glfwExtensions = glfwGetRequiredInstanceExtensions(&extensionsSize);
2020-03-16 20:21:04 +00:00
2020-03-31 13:22:15 +00:00
#ifndef NDEBUG
enabledLayerSize = 1;
enabledLayer = malloc(sizeof(char *));
enabledLayer[0] = "VK_LAYER_KHRONOS_validation";
2020-03-31 13:22:15 +00:00
#endif
2020-03-16 20:21:04 +00:00
2020-03-31 13:22:15 +00:00
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;
2020-03-16 20:21:04 +00:00
2020-03-31 13:22:15 +00:00
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;
2020-03-16 20:21:04 +00:00
2020-03-31 13:22:15 +00:00
ASSERT_VK(vkCreateInstance(&instanceCreateInfo, NULL, &(compute->instance)))
2020-03-16 20:21:04 +00:00
2020-03-31 13:22:15 +00:00
graphics->instance = compute->instance;
}
2020-03-16 20:21:04 +00:00
2020-03-31 13:22:15 +00:00
void findPhysicalDevice(Compute *compute, Graphics *graphics)
{
uint32_t devicesSize;
vkEnumeratePhysicalDevices(compute->instance, &devicesSize, NULL);
2020-03-16 20:21:04 +00:00
2020-03-31 13:22:15 +00:00
if (devicesSize <= 0)
{
printf("Fatal : No device found with Vulkan support!");
assert(devicesSize > 0);
}
2020-03-16 20:21:04 +00:00
2020-03-31 13:22:15 +00:00
VkPhysicalDevice physicalDevices[devicesSize];
vkEnumeratePhysicalDevices(compute->instance, &devicesSize, physicalDevices);
2020-03-16 20:21:04 +00:00
2020-03-31 13:22:15 +00:00
for (int i = 0; i < devicesSize; ++i)
2020-03-16 20:21:04 +00:00
{
2020-03-31 13:22:15 +00:00
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;
}
2020-03-16 20:21:04 +00:00
}
2020-03-31 13:22:15 +00:00
if (!compute->physicalDevice)
{
printf("Fatal : No device found with capable limits!");
assert(compute->physicalDevice);
}
2020-03-16 20:21:04 +00:00
2020-03-31 13:22:15 +00:00
graphics->physicalDevice = compute->physicalDevice;
}
2020-03-16 20:21:04 +00:00
2020-03-31 13:22:15 +00:00
uint32_t getQueueFamilyIndex(VkPhysicalDevice physicalDevice, VkQueueFlagBits queueFlagBits, int noGraphics)
{
uint32_t queueFamiliesSize;
vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueFamiliesSize, NULL);
VkQueueFamilyProperties queueFamilies[queueFamiliesSize];
vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueFamiliesSize, queueFamilies);
2020-03-16 20:21:04 +00:00
2020-03-31 13:22:15 +00:00
for (uint32_t i = 0; i < queueFamiliesSize; ++i)
2020-03-16 20:21:04 +00:00
{
2020-03-31 13:22:15 +00:00
if (noGraphics && (queueFamilies[i].queueFlags & VK_QUEUE_GRAPHICS_BIT))
{
}
else if ((queueFamilies[i].queueFlags & queueFlagBits) == queueFlagBits)
{
return i;
}
2020-03-16 20:21:04 +00:00
}
2020-03-31 13:22:15 +00:00
return UINT32_MAX;
2020-03-16 20:21:04 +00:00
}
2020-03-31 13:22:15 +00:00
void createDevice(Compute *compute, Graphics *graphics)
2020-03-16 20:21:04 +00:00
{
2020-03-31 13:22:15 +00:00
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);
}
2020-03-16 20:21:04 +00:00
2020-03-31 13:22:15 +00:00
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;
2020-03-16 20:21:04 +00:00
2020-03-31 13:22:15 +00:00
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);
}
2020-03-16 20:21:04 +00:00
2020-03-31 13:22:15 +00:00
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));
2020-03-16 20:21:04 +00:00
}
2020-03-31 13:22:15 +00:00
uint32_t findMemoryType(Compute *compute, uint32_t memoryTypeBits, VkMemoryPropertyFlags properties)
2020-03-16 20:21:04 +00:00
{
2020-03-31 13:22:15 +00:00
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;
}
2020-03-16 20:21:04 +00:00
2020-03-31 13:22:15 +00:00
return UINT32_MAX;
2020-03-16 20:21:04 +00:00
}
2020-03-31 13:22:15 +00:00
void createParticleBuffer(Compute *compute, Graphics *graphics)
2020-03-16 20:21:04 +00:00
{
2020-03-31 13:22:15 +00:00
uint32_t queueFamilyIndices[2] = {
compute->queueFamilyIndex,
graphics->queueFamilyIndex
2020-03-16 20:21:04 +00:00
};
2020-03-31 13:22:15 +00:00
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;
2020-03-16 20:21:04 +00:00
2020-03-31 13:22:15 +00:00
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))
}
2020-03-31 13:22:15 +00:00
void createComputeBuffer(Compute *compute, uint32_t bufferSize, VkBufferUsageFlags usageFlags, VkBuffer *buffer,
VkDeviceMemory *bufferMemory, VkMemoryPropertyFlags memoryPropertyFlags)
2020-03-18 15:55:27 +00:00
{
2020-03-31 13:22:15 +00:00
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))
2020-03-18 15:55:27 +00:00
}
2020-03-31 13:22:15 +00:00
void createComputeBuffers(Compute *compute)
2020-03-20 15:33:43 +00:00
{
2020-03-31 13:22:15 +00:00
// 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);
2020-03-20 15:33:43 +00:00
}
2020-03-31 13:22:15 +00:00
void createComputeDescriptorSetLayout(Compute *compute, VkDescriptorType descriptorType, VkDescriptorSetLayout *descriptorSetLayout)
2020-03-20 15:33:43 +00:00
{
2020-03-31 13:22:15 +00:00
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))
2020-03-20 15:33:43 +00:00
}
2020-03-31 13:22:15 +00:00
void createComputeDescriptorSetLayouts(Compute *compute)
2020-03-20 15:33:43 +00:00
{
2020-03-31 13:22:15 +00:00
// 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));
2020-03-20 15:33:43 +00:00
}
2020-03-31 13:22:15 +00:00
void createComputeDescriptorSet(Compute *compute, VkDescriptorType descriptorType, VkDescriptorPool *descriptorPool,
VkDescriptorSetLayout *descriptorSetLayout, VkDescriptorSet *descriptorSet,
VkBuffer buffer, uint32_t bufferSize)
2020-03-20 15:33:43 +00:00
{
2020-03-31 13:22:15 +00:00
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);
2020-03-20 15:33:43 +00:00
}
2020-03-31 13:22:15 +00:00
void createComputeDescriptorSets(Compute *compute)
2020-03-20 15:33:43 +00:00
{
2020-03-31 13:22:15 +00:00
// 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);
2020-03-20 15:33:43 +00:00
}
2020-03-31 13:22:15 +00:00
void createShaderModule(VkDevice device, char *filename, VkShaderModule *shaderModule)
2020-03-20 15:33:43 +00:00
{
2020-04-01 12:40:21 +00:00
size_t shaderSourceSize;
2020-03-31 13:22:15 +00:00
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);
2020-03-20 15:33:43 +00:00
}
2020-03-31 13:22:15 +00:00
void createComputePipeline(Compute *compute)
{
2020-03-31 13:22:15 +00:00
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)))
}
2020-03-31 13:22:15 +00:00
void mapBufferMemory(Compute *compute, VkDeviceMemory memory, void *inputData, uint32_t dataSize)
{
2020-03-31 13:22:15 +00:00
void *vkData;
vkMapMemory(compute->device, memory, 0, dataSize, 0, &vkData);
memcpy(vkData, inputData, dataSize);
vkUnmapMemory(compute->device, memory);
}
2020-03-31 13:22:15 +00:00
void copyBuffer(Compute *compute, VkBuffer src, VkBuffer dst, VkDeviceSize size)
2020-03-20 15:33:43 +00:00
{
2020-03-31 13:22:15 +00:00
uint32_t queueFamilyIndex = getQueueFamilyIndex(compute->physicalDevice, VK_QUEUE_TRANSFER_BIT, 0);
2020-03-31 13:22:15 +00:00
VkCommandPoolCreateInfo commandPoolCreateInfo = {};
commandPoolCreateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
commandPoolCreateInfo.flags = 0;
commandPoolCreateInfo.queueFamilyIndex = queueFamilyIndex;
2020-03-20 15:33:43 +00:00
2020-03-31 13:22:15 +00:00
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, &copyRegion);
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);
}
2020-03-31 13:22:15 +00:00
void fillComputeBuffer(Compute *compute, VkBuffer dst, void *data, uint32_t dataSize)
{
2020-03-31 13:22:15 +00:00
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);
2020-03-20 15:33:43 +00:00
}
2020-03-31 13:22:15 +00:00
void fillComputeBuffers(Compute *compute, float *particles, Dt *dtData, StaticIn *staticInData)
2020-03-16 20:21:04 +00:00
{
2020-03-31 13:22:15 +00:00
// Particle Buffer
fillComputeBuffer(compute, compute->particleBuffer, particles, compute->particleBufferSize);
2020-03-16 20:21:04 +00:00
2020-03-31 13:22:15 +00:00
// dt Buffer
mapBufferMemory(compute, compute->dtUniformBufferMemory, dtData, compute->dtUniformBufferSize);
2020-03-31 13:22:15 +00:00
// staticIn Buffer
fillComputeBuffer(compute, compute->staticInUniformBuffer, staticInData, compute->staticInUniformBufferSize);
}
2020-03-31 13:22:15 +00:00
void createComputeCommandBuffer(Compute *compute)
{
VkCommandPoolCreateInfo commandPoolCreateInfo = {};
commandPoolCreateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
commandPoolCreateInfo.flags = 0;
commandPoolCreateInfo.queueFamilyIndex = compute->queueFamilyIndex;
2020-03-20 15:33:43 +00:00
2020-03-31 13:22:15 +00:00
ASSERT_VK(vkCreateCommandPool(compute->device, &commandPoolCreateInfo, NULL, &(compute->commandPool)))
2020-03-20 15:33:43 +00:00
2020-03-31 13:22:15 +00:00
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;
2020-03-20 15:33:43 +00:00
2020-03-31 13:22:15 +00:00
ASSERT_VK(vkAllocateCommandBuffers(compute->device, &commandBufferAllocateInfo, &(compute->commandBuffer)))
2020-03-20 15:33:43 +00:00
2020-03-31 13:22:15 +00:00
VkCommandBufferBeginInfo beginInfo = {};
beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
beginInfo.flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT;
2020-03-18 15:55:27 +00:00
2020-03-31 13:22:15 +00:00
ASSERT_VK(vkBeginCommandBuffer(compute->commandBuffer, &beginInfo))
2020-03-18 15:55:27 +00:00
2020-03-31 13:22:15 +00:00
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);
2020-03-31 13:56:36 +00:00
vkCmdDispatch(compute->commandBuffer, PARTICLE_AMOUNT / WORKGROUP_SIZE_X, WORKGROUP_SIZE_Y, WORKGROUP_SIZE_Z);
2020-03-16 20:21:04 +00:00
2020-03-31 13:22:15 +00:00
ASSERT_VK(vkEndCommandBuffer(compute->commandBuffer))
2020-03-16 20:21:04 +00:00
}
2020-03-31 13:22:15 +00:00
void createSemaphore(VkDevice device, VkSemaphore *semaphore)
2020-03-16 20:21:04 +00:00
{
2020-03-31 13:22:15 +00:00
VkSemaphoreCreateInfo semaphoreCreateInfo = { .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO };
2020-03-31 13:56:36 +00:00
ASSERT_VK(vkCreateSemaphore(device, &semaphoreCreateInfo, NULL, semaphore))
2020-03-16 20:21:04 +00:00
}
2020-03-31 13:22:15 +00:00
void shutdownComputeVulkan(Compute *compute)
2020-03-18 15:55:27 +00:00
{
2020-03-31 13:22:15 +00:00
vkDeviceWaitIdle(compute->device);
vkDestroySemaphore(compute->device, compute->semaphore, NULL);
2020-03-18 15:55:27 +00:00
2020-03-31 13:22:15 +00:00
vkFreeMemory(compute->device, compute->particleBufferMemory, NULL);
vkFreeMemory(compute->device, compute->dtUniformBufferMemory, NULL);
vkFreeMemory(compute->device, compute->staticInUniformBufferMemory, NULL);
2020-03-18 15:55:27 +00:00
2020-03-31 13:22:15 +00:00
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);
2020-03-18 15:55:27 +00:00
}
2020-03-31 13:22:15 +00:00
void createGraphicsSurface(Graphics *graphics, GLFWwindow *window)
2020-03-18 15:55:27 +00:00
{
2020-03-31 13:22:15 +00:00
ASSERT_VK(glfwCreateWindowSurface(graphics->instance, window, NULL, &(graphics->surface)))
2020-03-18 15:55:27 +00:00
}
2020-03-31 13:22:15 +00:00
void createSwapchain(Graphics *graphics)
2020-03-18 15:55:27 +00:00
{
2020-03-31 13:22:15 +00:00
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])))
}
2020-03-18 15:55:27 +00:00
}
2020-03-31 13:22:15 +00:00
void createShaderStageInfo(VkPipelineShaderStageCreateInfo *shaderStageCreateInfo, VkShaderStageFlagBits shaderStageFlagBits,
VkShaderModule shaderModule)
2020-03-18 15:55:27 +00:00
{
2020-03-31 13:22:15 +00:00
shaderStageCreateInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
shaderStageCreateInfo->stage = shaderStageFlagBits;
shaderStageCreateInfo->module = shaderModule;
shaderStageCreateInfo->pName = "main";
2020-03-18 15:55:27 +00:00
}
2020-03-31 13:22:15 +00:00
void createGraphicsPipeline(Graphics *graphics)
2020-03-18 15:55:27 +00:00
{
2020-03-31 13:22:15 +00:00
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 = {};
2020-03-18 15:55:27 +00:00
viewport.x = 0.0f;
viewport.y = 0.0f;
2020-03-31 13:22:15 +00:00
viewport.width = WIDTH;
viewport.height = HEIGHT;
2020-03-18 15:55:27 +00:00
viewport.minDepth = 0.0f;
viewport.maxDepth = 1.0f;
2020-03-31 13:22:15 +00:00
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])))
}
2020-03-18 15:55:27 +00:00
}
2020-03-31 13:22:15 +00:00
void createGraphicsCommandBuffers(Graphics *graphics)
2020-03-18 15:55:27 +00:00
{
2020-03-31 13:22:15 +00:00
VkCommandPoolCreateInfo commandPoolInfo = {};
commandPoolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
commandPoolInfo.queueFamilyIndex = graphics->queueFamilyIndex;
2020-03-18 15:55:27 +00:00
2020-03-31 13:22:15 +00:00
ASSERT_VK(vkCreateCommandPool(graphics->device, &commandPoolInfo, NULL, &(graphics->commandPool)))
2020-03-18 15:55:27 +00:00
2020-03-31 13:22:15 +00:00
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;
2020-03-18 15:55:27 +00:00
2020-03-31 13:22:15 +00:00
graphics->commandBuffers = malloc(graphics->imageViewsSize * sizeof(VkCommandBuffer));
2020-03-18 15:55:27 +00:00
2020-03-31 13:22:15 +00:00
ASSERT_VK(vkAllocateCommandBuffers(graphics->device, &commandBufferAllocateInfo, graphics->commandBuffers))
2020-03-18 15:55:27 +00:00
2020-03-31 13:22:15 +00:00
VkCommandBufferBeginInfo commandBufferBeginInfo = {};
commandBufferBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
commandBufferBeginInfo.flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT;
2020-03-16 20:21:04 +00:00
2020-03-31 13:22:15 +00:00
VkRect2D renderArea = { {0, 0}, {WIDTH, HEIGHT} };
VkClearValue clearValue = {0, 0, 0, 1};
2020-03-16 20:21:04 +00:00
2020-03-31 13:22:15 +00:00
for (int i = 0; i < graphics->imageViewsSize; i++)
{
ASSERT_VK(vkBeginCommandBuffer(graphics->commandBuffers[i], &commandBufferBeginInfo))
2020-03-16 20:21:04 +00:00
2020-03-31 13:22:15 +00:00
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;
2020-03-16 20:21:04 +00:00
2020-03-31 13:22:15 +00:00
vkCmdBeginRenderPass(graphics->commandBuffers[i], &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
2020-03-16 20:21:04 +00:00
2020-03-31 13:22:15 +00:00
vkCmdBindPipeline(graphics->commandBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, graphics->pipeline);
2020-03-16 20:21:04 +00:00
2020-03-31 13:22:15 +00:00
VkDeviceSize offsets[1] = { 0 };
vkCmdBindVertexBuffers(graphics->commandBuffers[i], 0, 1, &(graphics->particleBuffer), offsets);
2020-03-16 20:21:04 +00:00
2020-03-31 13:22:15 +00:00
vkCmdDraw(graphics->commandBuffers[i], PARTICLE_AMOUNT, 1, 0, 0);
2020-03-16 20:21:04 +00:00
2020-03-31 13:22:15 +00:00
vkCmdEndRenderPass(graphics->commandBuffers[i]);
ASSERT_VK(vkEndCommandBuffer(graphics->commandBuffers[i]))
2020-03-16 20:21:04 +00:00
}
2020-03-31 13:22:15 +00:00
}
2020-03-16 20:21:04 +00:00
2020-03-31 13:22:15 +00:00
void shutdownGraphicsVulkan(Graphics *graphics)
{
vkDeviceWaitIdle(graphics->device);
for (int i = 0; i < graphics->imageViewsSize; ++i)
2020-03-16 20:21:04 +00:00
{
2020-03-31 13:22:15 +00:00
vkDestroyFramebuffer(graphics->device, graphics->framebuffers[i], NULL);
2020-03-16 20:21:04 +00:00
}
2020-03-31 13:22:15 +00:00
vkDestroyCommandPool(graphics->device, graphics->commandPool, NULL);
vkDestroySemaphore(graphics->device, graphics->semaphore, NULL);
vkDestroySemaphore(graphics->device, graphics->renderComplete, NULL);
vkDestroySemaphore(graphics->device, graphics->presentComplete, NULL);
2020-03-16 20:21:04 +00:00
2020-03-31 13:22:15 +00:00
vkDestroyPipelineLayout(graphics->device, graphics->pipelineLayout, NULL);
2020-03-16 20:21:04 +00:00
2020-03-31 13:22:15 +00:00
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)
2020-03-16 20:21:04 +00:00
{
2020-03-31 13:22:15 +00:00
vkDestroyImageView(graphics->device, graphics->imageViews[i], NULL);
2020-03-16 20:21:04 +00:00
}
2020-03-31 13:22:15 +00:00
vkDestroySwapchainKHR(graphics->device, graphics->swapChain, NULL);
vkDestroySurfaceKHR(graphics->instance, graphics->surface, NULL);
2020-03-16 20:21:04 +00:00
}