1
0

Compute finished (maybe);

Graphics ausstehend;
Aktuelles Problem: SEGFAULT bei Swapchain!
This commit is contained in:
Niklas Birk 2020-03-29 01:01:01 +01:00
parent bf5f9df90f
commit d5b566c2b6
7 changed files with 346 additions and 64 deletions

View File

@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.15) cmake_minimum_required(VERSION 3.10)
project(Informatikprojekt C) project(Informatikprojekt C)
set(CMAKE_C_STANDARD 11) set(CMAKE_C_STANDARD 11)

View File

@ -7,10 +7,18 @@ void shutdownGLFW(GLFWwindow *window)
glfwTerminate(); glfwTerminate();
} }
void createInstance(Compute *compute) void createInstance(Compute *compute, Graphics *graphics)
{ {
GLuint glfwExtensionsSize; GLuint enabledLayerSize = 0;
const char **glfwExtensions = glfwGetRequiredInstanceExtensions(&glfwExtensionsSize); 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 = {}; VkApplicationInfo applicationInfo = {};
applicationInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; applicationInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
@ -24,15 +32,17 @@ void createInstance(Compute *compute)
instanceCreateInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; instanceCreateInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
instanceCreateInfo.flags = 0; instanceCreateInfo.flags = 0;
instanceCreateInfo.pApplicationInfo = &applicationInfo; instanceCreateInfo.pApplicationInfo = &applicationInfo;
instanceCreateInfo.enabledLayerCount = 0; instanceCreateInfo.enabledLayerCount = enabledLayerSize;
instanceCreateInfo.ppEnabledLayerNames = NULL; instanceCreateInfo.ppEnabledLayerNames = enabledLayer;
instanceCreateInfo.enabledExtensionCount = glfwExtensionsSize; instanceCreateInfo.enabledExtensionCount = extensionsSize;
instanceCreateInfo.ppEnabledExtensionNames = glfwExtensions; instanceCreateInfo.ppEnabledExtensionNames = glfwExtensions;
ASSERT_VK(vkCreateInstance(&instanceCreateInfo, NULL, &(compute->instance))) ASSERT_VK(vkCreateInstance(&instanceCreateInfo, NULL, &(compute->instance)))
graphics->instance = compute->instance;
} }
void findPhysicalDevice(Compute *compute) void findPhysicalDevice(Compute *compute, Graphics *graphics)
{ {
uint32_t devicesSize; uint32_t devicesSize;
vkEnumeratePhysicalDevices(compute->instance, &devicesSize, NULL); vkEnumeratePhysicalDevices(compute->instance, &devicesSize, NULL);
@ -53,7 +63,7 @@ void findPhysicalDevice(Compute *compute)
if (WORKGROUP_SIZE_X <= deviceProperties.limits.maxComputeWorkGroupSize[0] if (WORKGROUP_SIZE_X <= deviceProperties.limits.maxComputeWorkGroupSize[0]
&& PARTICLE_AMOUNT / WORKGROUP_SIZE_X <= deviceProperties.limits.maxComputeWorkGroupCount[0] && PARTICLE_AMOUNT / WORKGROUP_SIZE_X <= deviceProperties.limits.maxComputeWorkGroupCount[0]
&& PARTICLE_SIZE * PARTICLE_AMOUNT <= deviceProperties.limits.maxStorageBufferRange) && (uint32_t) (PARTICLE_SIZE * PARTICLE_AMOUNT) <= deviceProperties.limits.maxStorageBufferRange)
{ {
compute->physicalDevice = physicalDevices[i]; compute->physicalDevice = physicalDevices[i];
break; break;
@ -65,6 +75,8 @@ void findPhysicalDevice(Compute *compute)
printf("Fatal : No device found with capable limits!"); printf("Fatal : No device found with capable limits!");
assert(compute->physicalDevice); assert(compute->physicalDevice);
} }
graphics->physicalDevice = compute->physicalDevice;
} }
uint32_t getQueueFamilyIndex(Compute *compute, VkQueueFlagBits queueFlagBits) uint32_t getQueueFamilyIndex(Compute *compute, VkQueueFlagBits queueFlagBits)
@ -76,7 +88,7 @@ uint32_t getQueueFamilyIndex(Compute *compute, VkQueueFlagBits queueFlagBits)
for (uint32_t i = 0; i < queueFamiliesSize; ++i) for (uint32_t i = 0; i < queueFamiliesSize; ++i)
{ {
if (queueFamilies[i].queueCount > 0 if (queueFamilies[i].queueCount >= 2
&& queueFamilies[i].queueFlags & queueFlagBits) && queueFamilies[i].queueFlags & queueFlagBits)
{ {
return i; return i;
@ -86,9 +98,10 @@ uint32_t getQueueFamilyIndex(Compute *compute, VkQueueFlagBits queueFlagBits)
return -1; return -1;
} }
void createDevice(Compute *compute) void createDevice(Compute *compute, Graphics *graphics)
{ {
compute->queueFamilyIndex = getQueueFamilyIndex(compute, VK_QUEUE_COMPUTE_BIT); compute->queueFamilyIndex = getQueueFamilyIndex(compute, VK_QUEUE_COMPUTE_BIT | VK_QUEUE_GRAPHICS_BIT);
graphics->queueFamilyIndex = compute->queueFamilyIndex;
if (compute->queueFamilyIndex < 0) if (compute->queueFamilyIndex < 0)
{ {
@ -96,23 +109,31 @@ void createDevice(Compute *compute)
assert(compute->queueFamilyIndex >= 0); assert(compute->queueFamilyIndex >= 0);
} }
float queuePriority = 1.0f;
VkDeviceQueueCreateInfo deviceQueueCreateInfo = {}; VkDeviceQueueCreateInfo deviceQueueCreateInfo = {};
deviceQueueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; deviceQueueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
deviceQueueCreateInfo.queueFamilyIndex = compute->queueFamilyIndex; deviceQueueCreateInfo.queueFamilyIndex = compute->queueFamilyIndex;
deviceQueueCreateInfo.queueCount = 1; deviceQueueCreateInfo.queueCount = 2;
deviceQueueCreateInfo.pQueuePriorities = NULL; deviceQueueCreateInfo.pQueuePriorities = &queuePriority;
VkPhysicalDeviceFeatures physicalDeviceFeatures = {}; VkPhysicalDeviceFeatures physicalDeviceFeatures = {};
const char *swapchainExtension = VK_KHR_SWAPCHAIN_EXTENSION_NAME;
const char **extensions = &swapchainExtension;
VkDeviceCreateInfo deviceCreateInfo = {}; VkDeviceCreateInfo deviceCreateInfo = {};
deviceCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; deviceCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
deviceCreateInfo.pQueueCreateInfos = &deviceQueueCreateInfo; deviceCreateInfo.pQueueCreateInfos = &deviceQueueCreateInfo;
deviceCreateInfo.queueCreateInfoCount = 1; deviceCreateInfo.queueCreateInfoCount = 1;
deviceCreateInfo.pEnabledFeatures = &physicalDeviceFeatures; deviceCreateInfo.pEnabledFeatures = &physicalDeviceFeatures;
deviceCreateInfo.enabledExtensionCount = 1;
deviceCreateInfo.ppEnabledExtensionNames = extensions;
ASSERT_VK(vkCreateDevice(compute->physicalDevice, &deviceCreateInfo, NULL, &(compute->device))) ASSERT_VK(vkCreateDevice(compute->physicalDevice, &deviceCreateInfo, NULL, &(compute->device)))
graphics->device = compute->device;
vkGetDeviceQueue(compute->device, compute->queueFamilyIndex, 0, &(compute->queue)); vkGetDeviceQueue(compute->device, compute->queueFamilyIndex, 0, &(compute->queue));
vkGetDeviceQueue(graphics->device, graphics->queueFamilyIndex, 1, &(graphics->queue));
} }
uint32_t findMemoryType(Compute *compute, uint32_t memoryTypeBits, VkMemoryPropertyFlags properties) uint32_t findMemoryType(Compute *compute, uint32_t memoryTypeBits, VkMemoryPropertyFlags properties)
@ -172,16 +193,17 @@ void createComputeBuffers(Compute *compute)
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
// staticIn Uniform Buffer // staticIn Uniform Buffer
createComputeBuffer(compute, compute->staticInUniformBufferSize, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, createComputeBuffer(compute, compute->staticInUniformBufferSize,
VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
&(compute->staticInUniformBuffer), &(compute->staticInUniformBuffer),
&(compute->staticInUniformBufferMemory), VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); &(compute->staticInUniformBufferMemory), VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
} }
void createComputeDescriptorSetLayout(Compute *compute, uint32_t binding, VkDescriptorType descriptorType, VkDescriptorSetLayout *descriptorSetLayout) void createComputeDescriptorSetLayout(Compute *compute, VkDescriptorType descriptorType, VkDescriptorSetLayout *descriptorSetLayout)
{ {
VkDescriptorSetLayoutBinding descriptorSetLayoutBinding = {}; VkDescriptorSetLayoutBinding descriptorSetLayoutBinding = {};
descriptorSetLayoutBinding.binding = binding; descriptorSetLayoutBinding.binding = 0;
descriptorSetLayoutBinding.descriptorType = descriptorType; descriptorSetLayoutBinding.descriptorType = descriptorType;
descriptorSetLayoutBinding.descriptorCount = 1; descriptorSetLayoutBinding.descriptorCount = 1;
descriptorSetLayoutBinding.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT; descriptorSetLayoutBinding.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT;
@ -197,15 +219,15 @@ void createComputeDescriptorSetLayout(Compute *compute, uint32_t binding, VkDesc
void createComputeDescriptorSetLayouts(Compute *compute) void createComputeDescriptorSetLayouts(Compute *compute)
{ {
// Particle Buffer // Particle Buffer
createComputeDescriptorSetLayout(compute, 0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, createComputeDescriptorSetLayout(compute, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
&(compute->particleBufferDescriptorSetLayout)); &(compute->particleBufferDescriptorSetLayout));
// dt Uniform Buffer // dt Uniform Buffer
createComputeDescriptorSetLayout(compute, 1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, createComputeDescriptorSetLayout(compute, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
&(compute->dtUniformBufferDescriptorSetLayout)); &(compute->dtUniformBufferDescriptorSetLayout));
// staticIn Uniform Buffer // staticIn Uniform Buffer
createComputeDescriptorSetLayout(compute, 2, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, createComputeDescriptorSetLayout(compute, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
&(compute->staticInUniformBufferDescriptorSetLayout)); &(compute->staticInUniformBufferDescriptorSetLayout));
} }
@ -269,19 +291,26 @@ void createComputeDescriptorSets(Compute *compute)
compute->staticInUniformBuffer, compute->staticInUniformBufferSize); 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) void createComputePipeline(Compute *compute)
{ {
long computeShaderSourceSize; createShaderModule(compute->device, "./vulkan/comp.spv", &(compute->shaderModule));
char *computeShaderSource = readFile("./vulkan/comp.spv", "rb", &computeShaderSourceSize);
VkShaderModuleCreateInfo shaderModuleCreateInfo = {};
shaderModuleCreateInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
shaderModuleCreateInfo.pCode = (uint32_t *) computeShaderSource;
shaderModuleCreateInfo.codeSize = computeShaderSourceSize;
ASSERT_VK(vkCreateShaderModule(compute->device, &shaderModuleCreateInfo, NULL, &(compute->shaderModule)))
free(computeShaderSource);
VkPipelineShaderStageCreateInfo pipelineShaderStageCreateInfo = {}; VkPipelineShaderStageCreateInfo pipelineShaderStageCreateInfo = {};
pipelineShaderStageCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; pipelineShaderStageCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
@ -299,12 +328,14 @@ void createComputePipeline(Compute *compute)
pipelineLayoutCreateInfo.setLayoutCount = 3; pipelineLayoutCreateInfo.setLayoutCount = 3;
pipelineLayoutCreateInfo.pSetLayouts = descriptorSetLayouts; pipelineLayoutCreateInfo.pSetLayouts = descriptorSetLayouts;
ASSERT_VK(vkCreatePipelineLayout(compute->device, &pipelineLayoutCreateInfo, NULL, &(compute->pipelineLayout))); ASSERT_VK(vkCreatePipelineLayout(compute->device, &pipelineLayoutCreateInfo, NULL, &(compute->pipelineLayout)))
VkComputePipelineCreateInfo pipelineCreateInfo = {}; VkComputePipelineCreateInfo pipelineCreateInfo = {};
pipelineCreateInfo.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO; pipelineCreateInfo.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO;
pipelineCreateInfo.stage = pipelineShaderStageCreateInfo; pipelineCreateInfo.stage = pipelineShaderStageCreateInfo;
pipelineCreateInfo.layout = compute->pipelineLayout; 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))) ASSERT_VK(vkCreateComputePipelines(compute->device, VK_NULL_HANDLE, 1, &pipelineCreateInfo, NULL, &(compute->pipeline)))
} }
@ -424,6 +455,12 @@ void createComputeCommandBuffer(Compute *compute)
ASSERT_VK(vkEndCommandBuffer(compute->commandBuffer)) 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 runComputeCommandBuffer(Compute *compute) void runComputeCommandBuffer(Compute *compute)
{ {
VkSubmitInfo submitInfo = {}; VkSubmitInfo submitInfo = {};
@ -440,7 +477,7 @@ void runComputeCommandBuffer(Compute *compute)
ASSERT_VK(vkQueueSubmit(compute->queue, 1, &submitInfo, fence)) ASSERT_VK(vkQueueSubmit(compute->queue, 1, &submitInfo, fence))
ASSERT_VK(vkWaitForFences(compute->device, 1, &fence, VK_TRUE, UINT64_MAX)); ASSERT_VK(vkWaitForFences(compute->device, 1, &fence, VK_TRUE, UINT64_MAX))
vkDestroyFence(compute->device, fence, NULL); vkDestroyFence(compute->device, fence, NULL);
} }
@ -455,7 +492,7 @@ void shutdownComputeVulkan(Compute *compute)
vkDestroyBuffer(compute->device, compute->dtUniformBuffer, NULL); vkDestroyBuffer(compute->device, compute->dtUniformBuffer, NULL);
vkDestroyBuffer(compute->device, compute->staticInUniformBuffer, NULL); vkDestroyBuffer(compute->device, compute->staticInUniformBuffer, NULL);
vkDestroyShaderModule(compute->device, compute->shaderModule, NULL); vkDestroyPipelineLayout(compute->device, compute->pipelineLayout, NULL);
vkDestroyDescriptorPool(compute->device, compute->particleBufferDescriptorPool, NULL); vkDestroyDescriptorPool(compute->device, compute->particleBufferDescriptorPool, NULL);
vkDestroyDescriptorPool(compute->device, compute->dtUniformBufferDescriptorPool, NULL); vkDestroyDescriptorPool(compute->device, compute->dtUniformBufferDescriptorPool, NULL);
@ -465,13 +502,225 @@ void shutdownComputeVulkan(Compute *compute)
vkDestroyDescriptorSetLayout(compute->device, compute->dtUniformBufferDescriptorSetLayout, NULL); vkDestroyDescriptorSetLayout(compute->device, compute->dtUniformBufferDescriptorSetLayout, NULL);
vkDestroyDescriptorSetLayout(compute->device, compute->staticInUniformBufferDescriptorSetLayout, NULL); vkDestroyDescriptorSetLayout(compute->device, compute->staticInUniformBufferDescriptorSetLayout, NULL);
vkDestroyPipelineLayout(compute->device, compute->pipelineLayout, NULL);
vkDestroyPipeline(compute->device, compute->pipeline, 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); vkDestroyCommandPool(compute->device, compute->commandPool, NULL);
vkDestroyDevice(compute->device, NULL); vkDestroyDevice(compute->device, NULL);
vkDestroyInstance(compute->instance, 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_FIFO_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)
{
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
};
VkPipelineVertexInputStateCreateInfo vertexInputStateInfo;
vertexInputStateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
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_POINT;
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_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;
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;
VkRenderPassCreateInfo renderPassInfo;
renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
renderPassInfo.attachmentCount = 1;
renderPassInfo.pAttachments = &attachmentDescription;
renderPassInfo.subpassCount = 1;
renderPassInfo.pSubpasses = &subpassDescription;
ASSERT_VK(vkCreateRenderPass(graphics->device, &renderPassInfo, NULL, &(graphics->renderPass)))
VkGraphicsPipelineCreateInfo graphicsPipelineInfo;
graphicsPipelineInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
graphicsPipelineInfo.stageCount = 3;
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 createGraphicsCommandBuffers(Graphics *graphics)
{
}

View File

@ -14,9 +14,9 @@
#define ENGINE_NAME "rwu_particles" #define ENGINE_NAME "rwu_particles"
#define ENGINE_VERSION VK_MAKE_VERSION(0, 0, 0) #define ENGINE_VERSION VK_MAKE_VERSION(0, 0, 0)
#define PARTICLE_AMOUNT 10 #define PARTICLE_AMOUNT 100
#define PARTICLE_SIZE (3 * sizeof(vector3f) + sizeof(float)) #define PARTICLE_SIZE (3 * sizeof(vector3f) + sizeof(float))
#define WORKGROUP_SIZE_X 256 #define WORKGROUP_SIZE_X 1024
#define WORKGROUP_SIZE_Y 1 #define WORKGROUP_SIZE_Y 1
#define WORKGROUP_SIZE_Z 1 #define WORKGROUP_SIZE_Z 1
@ -44,29 +44,31 @@ typedef struct compute {
VkCommandPool commandPool; VkCommandPool commandPool;
VkCommandBuffer commandBuffer; VkCommandBuffer commandBuffer;
VkDescriptorSetLayout particleBufferDescriptorSetLayout;
VkDescriptorPool particleBufferDescriptorPool; VkDescriptorPool particleBufferDescriptorPool;
VkDescriptorSet particleBufferDescriptorSet; VkDescriptorSet particleBufferDescriptorSet;
VkDescriptorSetLayout particleBufferDescriptorSetLayout;
VkBuffer particleBuffer; VkBuffer particleBuffer;
VkDeviceMemory particleBufferMemory; VkDeviceMemory particleBufferMemory;
uint32_t particleBufferSize; uint32_t particleBufferSize;
VkDescriptorSetLayout dtUniformBufferDescriptorSetLayout;
VkDescriptorPool dtUniformBufferDescriptorPool; VkDescriptorPool dtUniformBufferDescriptorPool;
VkDescriptorSet dtUniformBufferDescriptorSet; VkDescriptorSet dtUniformBufferDescriptorSet;
VkDescriptorSetLayout dtUniformBufferDescriptorSetLayout;
VkBuffer dtUniformBuffer; VkBuffer dtUniformBuffer;
VkDeviceMemory dtUniformBufferMemory; VkDeviceMemory dtUniformBufferMemory;
uint32_t dtUniformBufferSize; uint32_t dtUniformBufferSize;
VkDescriptorSetLayout staticInUniformBufferDescriptorSetLayout;
VkDescriptorPool staticInUniformBufferDescriptorPool; VkDescriptorPool staticInUniformBufferDescriptorPool;
VkDescriptorSet staticInUniformBufferDescriptorSet; VkDescriptorSet staticInUniformBufferDescriptorSet;
VkDescriptorSetLayout staticInUniformBufferDescriptorSetLayout;
VkBuffer staticInUniformBuffer; VkBuffer staticInUniformBuffer;
VkDeviceMemory staticInUniformBufferMemory; VkDeviceMemory staticInUniformBufferMemory;
uint32_t staticInUniformBufferSize; uint32_t staticInUniformBufferSize;
VkQueue queue; VkQueue queue;
uint32_t queueFamilyIndex; uint32_t queueFamilyIndex;
VkSemaphore semaphore;
} Compute; } Compute;
typedef struct graphics { typedef struct graphics {
@ -75,15 +77,30 @@ typedef struct graphics {
VkPhysicalDevice physicalDevice; VkPhysicalDevice physicalDevice;
VkDevice device; VkDevice device;
VkSurfaceKHR surface;
VkSwapchainKHR swapChain;
VkImageView *imageViews;
uint32_t imageViewsSize;
VkRenderPass renderPass;
VkFramebuffer *framebuffers;
VkPipeline pipeline; VkPipeline pipeline;
VkPipelineLayout pipelineLayout; VkPipelineLayout pipelineLayout;
VkShaderModule shaderModule; VkShaderModule vertexShaderModule;
VkShaderModule fragmentShaderModule;
VkCommandPool commandPool; VkCommandPool commandPool;
VkCommandBuffer commandBuffer; VkCommandBuffer commandBuffer;
VkBuffer particleBuffer;
uint32_t particleBufferSize;
VkQueue queue; VkQueue queue;
uint32_t queueFamilyIndex; uint32_t queueFamilyIndex;
VkSemaphore semaphore;
} Graphics; } Graphics;
typedef struct dt { typedef struct dt {
@ -91,7 +108,9 @@ typedef struct dt {
} Dt; } Dt;
typedef struct staticIn { typedef struct staticIn {
float x, y, z; float x;
float y;
float z;
unsigned int maxParticles; unsigned int maxParticles;
} StaticIn; } StaticIn;
@ -99,9 +118,9 @@ typedef struct staticIn {
void shutdownGLFW(GLFWwindow *window); void shutdownGLFW(GLFWwindow *window);
void shutdownComputeVulkan(Compute *compute); void shutdownComputeVulkan(Compute *compute);
void createInstance(Compute *compute); void createInstance(Compute *compute, Graphics *graphics);
void findPhysicalDevice(Compute *compute); void findPhysicalDevice(Compute *compute, Graphics *graphics);
void createDevice(Compute *compute); void createDevice(Compute *compute, Graphics *graphics);
// Compute // Compute
void createComputeBuffers(Compute *compute); void createComputeBuffers(Compute *compute);
@ -112,5 +131,12 @@ void fillComputeBuffers(Compute *compute, float *particles, Dt *dtData, StaticIn
void createComputeCommandBuffer(Compute *compute); void createComputeCommandBuffer(Compute *compute);
void runComputeCommandBuffer(Compute *compute); void runComputeCommandBuffer(Compute *compute);
// Graphics
void createGraphicsSurface(Graphics *graphics, GLFWwindow *window);
void createSwapchain(Graphics *graphics);
void createGraphicsPipeline(Graphics *graphics);
void createGraphicsCommandBuffers(Graphics *graphics);
// ELse // ELse
void mapBufferMemory(Compute *compute, VkDeviceMemory memory, void *inputData, uint32_t dataSize); void mapBufferMemory(Compute *compute, VkDeviceMemory memory, void *inputData, uint32_t dataSize);
void createSemaphore(VkDevice device, VkSemaphore *semaphore);

View File

@ -11,7 +11,6 @@ int main()
(ps->emitters)[0] = e1; (ps->emitters)[0] = e1;
initRandomParticles(e1); initRandomParticles(e1);
float *particles = serializeParticlesystem(ps); float *particles = serializeParticlesystem(ps);
freeParticleSystem(ps);
Dt dt = { 0.5f }; Dt dt = { 0.5f };
StaticIn staticIn = { StaticIn staticIn = {
@ -21,6 +20,8 @@ int main()
PARTICLE_AMOUNT PARTICLE_AMOUNT
}; };
freeParticleSystem(ps);
/************* INIT GLFW *************/ /************* INIT GLFW *************/
ASSERT_GLFW_SUCCESS(glfwInit()); ASSERT_GLFW_SUCCESS(glfwInit());
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
@ -28,32 +29,38 @@ int main()
GLFWwindow *window = glfwCreateWindow(WIDTH, HEIGHT, "Informatikprojekt - Vulkan", NULL, NULL); GLFWwindow *window = glfwCreateWindow(WIDTH, HEIGHT, "Informatikprojekt - Vulkan", NULL, NULL);
/************* INIT VULKAN *************/ /************* INIT VULKAN *************/
// Compute
Compute compute = { Compute compute = {
.particleBufferSize = PARTICLE_SIZE * PARTICLE_AMOUNT, .particleBufferSize = PARTICLE_SIZE * PARTICLE_AMOUNT,
.staticInUniformBufferSize = sizeof(StaticIn), .staticInUniformBufferSize = sizeof(StaticIn),
.dtUniformBufferSize = sizeof(Dt) .dtUniformBufferSize = sizeof(Dt)
}; };
createInstance(&compute); Graphics graphics = {};
findPhysicalDevice(&compute);
createDevice(&compute); // General
createInstance(&compute, &graphics);
findPhysicalDevice(&compute, &graphics);
createDevice(&compute, &graphics);
// Compute
createComputeBuffers(&compute); createComputeBuffers(&compute);
createComputeDescriptorSetLayouts(&compute); createComputeDescriptorSetLayouts(&compute);
createComputeDescriptorSets(&compute); createComputeDescriptorSets(&compute);
createComputePipeline(&compute); createComputePipeline(&compute);
fillComputeBuffers(&compute, particles, &dt, &staticIn); fillComputeBuffers(&compute, particles, &dt, &staticIn);
createComputeCommandBuffer(&compute); createComputeCommandBuffer(&compute);
createSemaphore(compute.device, &(compute.semaphore));
// Graphics // Graphics
Graphics graphics = { createGraphicsSurface(&graphics, window);
.instance = compute.instance, createSwapchain(&graphics);
.physicalDevice = compute.physicalDevice, createGraphicsPipeline(&graphics);
.device = compute.device, createGraphicsCommandBuffers(&graphics);
}; createSemaphore(graphics.device, &(graphics.semaphore));
/************* RENDER LOOP *************/ /************* RENDER LOOP *************/
double time, tLast = 0; double time, tLast = 0;
Dt tFrame = { 1.0f }; Dt tFrame = {};
while (!glfwWindowShouldClose(window)) while (!glfwWindowShouldClose(window))
{ {
time = glfwGetTime(); time = glfwGetTime();

View File

@ -3,7 +3,7 @@
#include "initOpenGL.h" #include "initOpenGL.h"
#include "utils.h" #include "utils.h"
#define PARTICLE_AMOUNT 15000000 #define PARTICLE_AMOUNT 10000
int main() int main()
{ {
@ -86,7 +86,7 @@ int main()
/*** UPDATE ***/ /*** UPDATE ***/
glUseProgram(computeShaderProgram); glUseProgram(computeShaderProgram);
glUniform1f(dtUniformLocation, tFrame); glUniform1f(dtUniformLocation, tFrame);
glDispatchCompute(PARTICLE_AMOUNT / 256, 1, 1); glDispatchCompute(PARTICLE_AMOUNT / 1024, 1, 1);
glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT | GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT); glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT | GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT);
/*** RENDER ***/ /*** RENDER ***/

View File

@ -20,7 +20,7 @@ layout(location = 0) uniform float dt;
layout(location = 1) uniform vec3 resetPos; layout(location = 1) uniform vec3 resetPos;
layout(location = 2) uniform uint maxParticles; layout(location = 2) uniform uint maxParticles;
layout (local_size_x = 256, local_size_y = 1, local_size_z = 1) in; layout (local_size_x = 1024, local_size_y = 1, local_size_z = 1) in;
uint hash(uvec3 seed) uint hash(uvec3 seed)
{ {

View File

@ -11,23 +11,23 @@ struct particle
float age; float age;
}; };
layout(std430, binding = 0) buffer particles layout(std430, set = 0, binding = 0) buffer particles
{ {
particle p[]; particle p[];
}; };
layout(binding = 1) uniform dtIn layout(set = 1, binding = 0) uniform dtIn
{ {
float dt; float dt;
}; };
layout(binding = 2) uniform staticIn layout(set = 2, binding = 0) uniform staticIn
{ {
vec3 resetPos; vec3 resetPos;
uint maxParticles; uint maxParticles;
}; };
layout (local_size_x = 256, local_size_y = 1, local_size_z = 1) in; layout (local_size_x = 1024, local_size_y = 1, local_size_z = 1) in;
uint hash(uvec3 seed) uint hash(uvec3 seed)
{ {