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)
set(CMAKE_C_STANDARD 11)

View File

@ -7,10 +7,18 @@ void shutdownGLFW(GLFWwindow *window)
glfwTerminate();
}
void createInstance(Compute *compute)
void createInstance(Compute *compute, Graphics *graphics)
{
GLuint glfwExtensionsSize;
const char **glfwExtensions = glfwGetRequiredInstanceExtensions(&glfwExtensionsSize);
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;
@ -24,15 +32,17 @@ void createInstance(Compute *compute)
instanceCreateInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
instanceCreateInfo.flags = 0;
instanceCreateInfo.pApplicationInfo = &applicationInfo;
instanceCreateInfo.enabledLayerCount = 0;
instanceCreateInfo.ppEnabledLayerNames = NULL;
instanceCreateInfo.enabledExtensionCount = glfwExtensionsSize;
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)
void findPhysicalDevice(Compute *compute, Graphics *graphics)
{
uint32_t devicesSize;
vkEnumeratePhysicalDevices(compute->instance, &devicesSize, NULL);
@ -53,7 +63,7 @@ void findPhysicalDevice(Compute *compute)
if (WORKGROUP_SIZE_X <= deviceProperties.limits.maxComputeWorkGroupSize[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];
break;
@ -65,6 +75,8 @@ void findPhysicalDevice(Compute *compute)
printf("Fatal : No device found with capable limits!");
assert(compute->physicalDevice);
}
graphics->physicalDevice = compute->physicalDevice;
}
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)
{
if (queueFamilies[i].queueCount > 0
if (queueFamilies[i].queueCount >= 2
&& queueFamilies[i].queueFlags & queueFlagBits)
{
return i;
@ -86,9 +98,10 @@ uint32_t getQueueFamilyIndex(Compute *compute, VkQueueFlagBits queueFlagBits)
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)
{
@ -96,23 +109,31 @@ void createDevice(Compute *compute)
assert(compute->queueFamilyIndex >= 0);
}
float queuePriority = 1.0f;
VkDeviceQueueCreateInfo deviceQueueCreateInfo = {};
deviceQueueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
deviceQueueCreateInfo.queueFamilyIndex = compute->queueFamilyIndex;
deviceQueueCreateInfo.queueCount = 1;
deviceQueueCreateInfo.pQueuePriorities = NULL;
deviceQueueCreateInfo.queueCount = 2;
deviceQueueCreateInfo.pQueuePriorities = &queuePriority;
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.pQueueCreateInfos = &deviceQueueCreateInfo;
deviceCreateInfo.queueCreateInfoCount = 1;
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, 1, &(graphics->queue));
}
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);
// 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->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 = {};
descriptorSetLayoutBinding.binding = binding;
descriptorSetLayoutBinding.binding = 0;
descriptorSetLayoutBinding.descriptorType = descriptorType;
descriptorSetLayoutBinding.descriptorCount = 1;
descriptorSetLayoutBinding.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT;
@ -197,15 +219,15 @@ void createComputeDescriptorSetLayout(Compute *compute, uint32_t binding, VkDesc
void createComputeDescriptorSetLayouts(Compute *compute)
{
// Particle Buffer
createComputeDescriptorSetLayout(compute, 0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
createComputeDescriptorSetLayout(compute, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
&(compute->particleBufferDescriptorSetLayout));
// dt Uniform Buffer
createComputeDescriptorSetLayout(compute, 1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
createComputeDescriptorSetLayout(compute, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
&(compute->dtUniformBufferDescriptorSetLayout));
// staticIn Uniform Buffer
createComputeDescriptorSetLayout(compute, 2, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
createComputeDescriptorSetLayout(compute, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
&(compute->staticInUniformBufferDescriptorSetLayout));
}
@ -269,19 +291,26 @@ void createComputeDescriptorSets(Compute *compute)
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)
{
long computeShaderSourceSize;
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);
createShaderModule(compute->device, "./vulkan/comp.spv", &(compute->shaderModule));
VkPipelineShaderStageCreateInfo pipelineShaderStageCreateInfo = {};
pipelineShaderStageCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
@ -299,12 +328,14 @@ void createComputePipeline(Compute *compute)
pipelineLayoutCreateInfo.setLayoutCount = 3;
pipelineLayoutCreateInfo.pSetLayouts = descriptorSetLayouts;
ASSERT_VK(vkCreatePipelineLayout(compute->device, &pipelineLayoutCreateInfo, NULL, &(compute->pipelineLayout)));
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)))
}
@ -424,6 +455,12 @@ void createComputeCommandBuffer(Compute *compute)
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)
{
VkSubmitInfo submitInfo = {};
@ -440,7 +477,7 @@ void runComputeCommandBuffer(Compute *compute)
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);
}
@ -455,7 +492,7 @@ void shutdownComputeVulkan(Compute *compute)
vkDestroyBuffer(compute->device, compute->dtUniformBuffer, 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->dtUniformBufferDescriptorPool, NULL);
@ -465,13 +502,225 @@ void shutdownComputeVulkan(Compute *compute)
vkDestroyDescriptorSetLayout(compute->device, compute->dtUniformBufferDescriptorSetLayout, NULL);
vkDestroyDescriptorSetLayout(compute->device, compute->staticInUniformBufferDescriptorSetLayout, NULL);
vkDestroyPipelineLayout(compute->device, compute->pipelineLayout, 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_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_VERSION VK_MAKE_VERSION(0, 0, 0)
#define PARTICLE_AMOUNT 10
#define PARTICLE_AMOUNT 100
#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_Z 1
@ -44,29 +44,31 @@ typedef struct compute {
VkCommandPool commandPool;
VkCommandBuffer commandBuffer;
VkDescriptorSetLayout particleBufferDescriptorSetLayout;
VkDescriptorPool particleBufferDescriptorPool;
VkDescriptorSet particleBufferDescriptorSet;
VkDescriptorSetLayout particleBufferDescriptorSetLayout;
VkBuffer particleBuffer;
VkDeviceMemory particleBufferMemory;
uint32_t particleBufferSize;
VkDescriptorSetLayout dtUniformBufferDescriptorSetLayout;
VkDescriptorPool dtUniformBufferDescriptorPool;
VkDescriptorSet dtUniformBufferDescriptorSet;
VkDescriptorSetLayout dtUniformBufferDescriptorSetLayout;
VkBuffer dtUniformBuffer;
VkDeviceMemory dtUniformBufferMemory;
uint32_t dtUniformBufferSize;
VkDescriptorSetLayout staticInUniformBufferDescriptorSetLayout;
VkDescriptorPool staticInUniformBufferDescriptorPool;
VkDescriptorSet staticInUniformBufferDescriptorSet;
VkDescriptorSetLayout staticInUniformBufferDescriptorSetLayout;
VkBuffer staticInUniformBuffer;
VkDeviceMemory staticInUniformBufferMemory;
uint32_t staticInUniformBufferSize;
VkQueue queue;
uint32_t queueFamilyIndex;
VkSemaphore semaphore;
} Compute;
typedef struct graphics {
@ -75,15 +77,30 @@ typedef struct graphics {
VkPhysicalDevice physicalDevice;
VkDevice device;
VkSurfaceKHR surface;
VkSwapchainKHR swapChain;
VkImageView *imageViews;
uint32_t imageViewsSize;
VkRenderPass renderPass;
VkFramebuffer *framebuffers;
VkPipeline pipeline;
VkPipelineLayout pipelineLayout;
VkShaderModule shaderModule;
VkShaderModule vertexShaderModule;
VkShaderModule fragmentShaderModule;
VkCommandPool commandPool;
VkCommandBuffer commandBuffer;
VkBuffer particleBuffer;
uint32_t particleBufferSize;
VkQueue queue;
uint32_t queueFamilyIndex;
VkSemaphore semaphore;
} Graphics;
typedef struct dt {
@ -91,7 +108,9 @@ typedef struct dt {
} Dt;
typedef struct staticIn {
float x, y, z;
float x;
float y;
float z;
unsigned int maxParticles;
} StaticIn;
@ -99,9 +118,9 @@ typedef struct staticIn {
void shutdownGLFW(GLFWwindow *window);
void shutdownComputeVulkan(Compute *compute);
void createInstance(Compute *compute);
void findPhysicalDevice(Compute *compute);
void createDevice(Compute *compute);
void createInstance(Compute *compute, Graphics *graphics);
void findPhysicalDevice(Compute *compute, Graphics *graphics);
void createDevice(Compute *compute, Graphics *graphics);
// Compute
void createComputeBuffers(Compute *compute);
@ -112,5 +131,12 @@ void fillComputeBuffers(Compute *compute, float *particles, Dt *dtData, StaticIn
void createComputeCommandBuffer(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
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;
initRandomParticles(e1);
float *particles = serializeParticlesystem(ps);
freeParticleSystem(ps);
Dt dt = { 0.5f };
StaticIn staticIn = {
@ -21,6 +20,8 @@ int main()
PARTICLE_AMOUNT
};
freeParticleSystem(ps);
/************* INIT GLFW *************/
ASSERT_GLFW_SUCCESS(glfwInit());
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
@ -28,32 +29,38 @@ int main()
GLFWwindow *window = glfwCreateWindow(WIDTH, HEIGHT, "Informatikprojekt - Vulkan", NULL, NULL);
/************* INIT VULKAN *************/
// Compute
Compute compute = {
.particleBufferSize = PARTICLE_SIZE * PARTICLE_AMOUNT,
.staticInUniformBufferSize = sizeof(StaticIn),
.dtUniformBufferSize = sizeof(Dt)
};
createInstance(&compute);
findPhysicalDevice(&compute);
createDevice(&compute);
Graphics graphics = {};
// General
createInstance(&compute, &graphics);
findPhysicalDevice(&compute, &graphics);
createDevice(&compute, &graphics);
// Compute
createComputeBuffers(&compute);
createComputeDescriptorSetLayouts(&compute);
createComputeDescriptorSets(&compute);
createComputePipeline(&compute);
fillComputeBuffers(&compute, particles, &dt, &staticIn);
createComputeCommandBuffer(&compute);
createSemaphore(compute.device, &(compute.semaphore));
// Graphics
Graphics graphics = {
.instance = compute.instance,
.physicalDevice = compute.physicalDevice,
.device = compute.device,
};
createGraphicsSurface(&graphics, window);
createSwapchain(&graphics);
createGraphicsPipeline(&graphics);
createGraphicsCommandBuffers(&graphics);
createSemaphore(graphics.device, &(graphics.semaphore));
/************* RENDER LOOP *************/
double time, tLast = 0;
Dt tFrame = { 1.0f };
Dt tFrame = {};
while (!glfwWindowShouldClose(window))
{
time = glfwGetTime();

View File

@ -3,7 +3,7 @@
#include "initOpenGL.h"
#include "utils.h"
#define PARTICLE_AMOUNT 15000000
#define PARTICLE_AMOUNT 10000
int main()
{
@ -86,7 +86,7 @@ int main()
/*** UPDATE ***/
glUseProgram(computeShaderProgram);
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);
/*** RENDER ***/

View File

@ -20,7 +20,7 @@ layout(location = 0) uniform float dt;
layout(location = 1) uniform vec3 resetPos;
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)
{

View File

@ -11,23 +11,23 @@ struct particle
float age;
};
layout(std430, binding = 0) buffer particles
layout(std430, set = 0, binding = 0) buffer particles
{
particle p[];
};
layout(binding = 1) uniform dtIn
layout(set = 1, binding = 0) uniform dtIn
{
float dt;
};
layout(binding = 2) uniform staticIn
layout(set = 2, binding = 0) uniform staticIn
{
vec3 resetPos;
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)
{