Finally finished vulkan to draw
This commit is contained in:
parent
d5b566c2b6
commit
c99023f81c
@ -79,42 +79,60 @@ void findPhysicalDevice(Compute *compute, Graphics *graphics)
|
|||||||
graphics->physicalDevice = compute->physicalDevice;
|
graphics->physicalDevice = compute->physicalDevice;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t getQueueFamilyIndex(Compute *compute, VkQueueFlagBits queueFlagBits)
|
uint32_t getQueueFamilyIndex(VkPhysicalDevice physicalDevice, VkQueueFlagBits queueFlagBits, int noGraphics)
|
||||||
{
|
{
|
||||||
uint32_t queueFamiliesSize;
|
uint32_t queueFamiliesSize;
|
||||||
vkGetPhysicalDeviceQueueFamilyProperties(compute->physicalDevice, &queueFamiliesSize, NULL);
|
vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueFamiliesSize, NULL);
|
||||||
VkQueueFamilyProperties queueFamilies[queueFamiliesSize];
|
VkQueueFamilyProperties queueFamilies[queueFamiliesSize];
|
||||||
vkGetPhysicalDeviceQueueFamilyProperties(compute->physicalDevice, &queueFamiliesSize, queueFamilies);
|
vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueFamiliesSize, queueFamilies);
|
||||||
|
|
||||||
for (uint32_t i = 0; i < queueFamiliesSize; ++i)
|
for (uint32_t i = 0; i < queueFamiliesSize; ++i)
|
||||||
{
|
{
|
||||||
if (queueFamilies[i].queueCount >= 2
|
if (noGraphics && (queueFamilies[i].queueFlags & VK_QUEUE_GRAPHICS_BIT))
|
||||||
&& queueFamilies[i].queueFlags & queueFlagBits)
|
{
|
||||||
|
}
|
||||||
|
else if ((queueFamilies[i].queueFlags & queueFlagBits) == queueFlagBits)
|
||||||
{
|
{
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return UINT32_MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
void createDevice(Compute *compute, Graphics *graphics)
|
void createDevice(Compute *compute, Graphics *graphics)
|
||||||
{
|
{
|
||||||
compute->queueFamilyIndex = getQueueFamilyIndex(compute, VK_QUEUE_COMPUTE_BIT | VK_QUEUE_GRAPHICS_BIT);
|
compute->queueFamilyIndex = getQueueFamilyIndex(compute->physicalDevice, VK_QUEUE_COMPUTE_BIT, 1);
|
||||||
graphics->queueFamilyIndex = compute->queueFamilyIndex;
|
if (compute->queueFamilyIndex == UINT32_MAX)
|
||||||
|
|
||||||
if (compute->queueFamilyIndex < 0)
|
|
||||||
{
|
{
|
||||||
printf("Fatal: Could not find a queue family with capability of computing!");
|
printf("ERROR: No Queue family found with desired capabilities!\n");
|
||||||
assert(compute->queueFamilyIndex >= 0);
|
assert( compute->queueFamilyIndex < UINT32_MAX);
|
||||||
}
|
}
|
||||||
|
|
||||||
float queuePriority = 1.0f;
|
float queuePriority = 1.0f;
|
||||||
VkDeviceQueueCreateInfo deviceQueueCreateInfo = {};
|
VkDeviceQueueCreateInfo computeDeviceQueueCreateInfo = {};
|
||||||
deviceQueueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
|
computeDeviceQueueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
|
||||||
deviceQueueCreateInfo.queueFamilyIndex = compute->queueFamilyIndex;
|
computeDeviceQueueCreateInfo.queueFamilyIndex = compute->queueFamilyIndex;
|
||||||
deviceQueueCreateInfo.queueCount = 2;
|
computeDeviceQueueCreateInfo.queueCount = 1;
|
||||||
deviceQueueCreateInfo.pQueuePriorities = &queuePriority;
|
computeDeviceQueueCreateInfo.pQueuePriorities = &queuePriority;
|
||||||
|
|
||||||
|
graphics->queueFamilyIndex = getQueueFamilyIndex(graphics->physicalDevice, VK_QUEUE_GRAPHICS_BIT, 0);
|
||||||
|
if (graphics->queueFamilyIndex == UINT32_MAX)
|
||||||
|
{
|
||||||
|
printf("ERROR: No Queue family found with desired capabilities!\n");
|
||||||
|
assert( compute->queueFamilyIndex < UINT32_MAX);
|
||||||
|
}
|
||||||
|
|
||||||
|
VkDeviceQueueCreateInfo graphicsDeviceQueueCreateInfo = {};
|
||||||
|
graphicsDeviceQueueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
|
||||||
|
graphicsDeviceQueueCreateInfo.queueFamilyIndex = graphics->queueFamilyIndex;
|
||||||
|
graphicsDeviceQueueCreateInfo.queueCount = 1;
|
||||||
|
graphicsDeviceQueueCreateInfo.pQueuePriorities = &queuePriority;
|
||||||
|
|
||||||
|
VkDeviceQueueCreateInfo deviceQueueCreateInfos[2] = {
|
||||||
|
computeDeviceQueueCreateInfo,
|
||||||
|
graphicsDeviceQueueCreateInfo
|
||||||
|
};
|
||||||
|
|
||||||
VkPhysicalDeviceFeatures physicalDeviceFeatures = {};
|
VkPhysicalDeviceFeatures physicalDeviceFeatures = {};
|
||||||
const char *swapchainExtension = VK_KHR_SWAPCHAIN_EXTENSION_NAME;
|
const char *swapchainExtension = VK_KHR_SWAPCHAIN_EXTENSION_NAME;
|
||||||
@ -122,8 +140,8 @@ void createDevice(Compute *compute, Graphics *graphics)
|
|||||||
|
|
||||||
VkDeviceCreateInfo deviceCreateInfo = {};
|
VkDeviceCreateInfo deviceCreateInfo = {};
|
||||||
deviceCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
|
deviceCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
|
||||||
deviceCreateInfo.pQueueCreateInfos = &deviceQueueCreateInfo;
|
deviceCreateInfo.queueCreateInfoCount = 2;
|
||||||
deviceCreateInfo.queueCreateInfoCount = 1;
|
deviceCreateInfo.pQueueCreateInfos = deviceQueueCreateInfos;
|
||||||
deviceCreateInfo.pEnabledFeatures = &physicalDeviceFeatures;
|
deviceCreateInfo.pEnabledFeatures = &physicalDeviceFeatures;
|
||||||
deviceCreateInfo.enabledExtensionCount = 1;
|
deviceCreateInfo.enabledExtensionCount = 1;
|
||||||
deviceCreateInfo.ppEnabledExtensionNames = extensions;
|
deviceCreateInfo.ppEnabledExtensionNames = extensions;
|
||||||
@ -133,7 +151,7 @@ void createDevice(Compute *compute, Graphics *graphics)
|
|||||||
graphics->device = 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));
|
vkGetDeviceQueue(graphics->device, graphics->queueFamilyIndex, 0, &(graphics->queue));
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t findMemoryType(Compute *compute, uint32_t memoryTypeBits, VkMemoryPropertyFlags properties)
|
uint32_t findMemoryType(Compute *compute, uint32_t memoryTypeBits, VkMemoryPropertyFlags properties)
|
||||||
@ -148,44 +166,69 @@ uint32_t findMemoryType(Compute *compute, uint32_t memoryTypeBits, VkMemoryPrope
|
|||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return UINT32_MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
void createComputeBuffer(Compute *compute, uint32_t bufferSize, VkBufferUsageFlags usageFlags, VkBuffer *buffer,
|
void createParticleBuffer(Compute *compute, Graphics *graphics)
|
||||||
VkDeviceMemory *bufferMemory, VkMemoryPropertyFlags memoryPropertyFlags)
|
|
||||||
{
|
{
|
||||||
|
uint32_t queueFamilyIndices[2] = {
|
||||||
|
compute->queueFamilyIndex,
|
||||||
|
graphics->queueFamilyIndex
|
||||||
|
};
|
||||||
|
|
||||||
VkBufferCreateInfo particleBufferCreateInfo = {};
|
VkBufferCreateInfo particleBufferCreateInfo = {};
|
||||||
particleBufferCreateInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
|
particleBufferCreateInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
|
||||||
particleBufferCreateInfo.size = bufferSize;
|
particleBufferCreateInfo.size = compute->particleBufferSize;
|
||||||
particleBufferCreateInfo.usage = usageFlags;
|
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_EXCLUSIVE;
|
particleBufferCreateInfo.sharingMode = VK_SHARING_MODE_CONCURRENT;
|
||||||
|
particleBufferCreateInfo.queueFamilyIndexCount = 2;
|
||||||
|
particleBufferCreateInfo.pQueueFamilyIndices = queueFamilyIndices;
|
||||||
|
|
||||||
ASSERT_VK(vkCreateBuffer(compute->device, &particleBufferCreateInfo, NULL, buffer))
|
ASSERT_VK(vkCreateBuffer(compute->device, &particleBufferCreateInfo, NULL, &(compute->particleBuffer)))
|
||||||
|
|
||||||
VkMemoryRequirements particleBufferMemoryRequirements;
|
VkMemoryRequirements particleBufferMemoryRequirements;
|
||||||
vkGetBufferMemoryRequirements(compute->device, *buffer, &particleBufferMemoryRequirements);
|
vkGetBufferMemoryRequirements(compute->device, compute->particleBuffer, &particleBufferMemoryRequirements);
|
||||||
|
|
||||||
VkMemoryAllocateInfo particleMemoryAllocateInfo = {};
|
VkMemoryAllocateInfo particleMemoryAllocateInfo = {};
|
||||||
particleMemoryAllocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
|
particleMemoryAllocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
|
||||||
particleMemoryAllocateInfo.allocationSize = particleBufferMemoryRequirements.size;
|
particleMemoryAllocateInfo.allocationSize = particleBufferMemoryRequirements.size;
|
||||||
particleMemoryAllocateInfo.memoryTypeIndex = findMemoryType(compute,
|
particleMemoryAllocateInfo.memoryTypeIndex = findMemoryType(compute,
|
||||||
particleBufferMemoryRequirements.memoryTypeBits,
|
particleBufferMemoryRequirements.memoryTypeBits,
|
||||||
|
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
|
||||||
|
|
||||||
|
ASSERT_VK(vkAllocateMemory(compute->device, &particleMemoryAllocateInfo, NULL, &(compute->particleBufferMemory)))
|
||||||
|
|
||||||
|
ASSERT_VK(vkBindBufferMemory(compute->device, compute->particleBuffer, compute->particleBufferMemory, 0))
|
||||||
|
}
|
||||||
|
|
||||||
|
void createComputeBuffer(Compute *compute, uint32_t bufferSize, VkBufferUsageFlags usageFlags, VkBuffer *buffer,
|
||||||
|
VkDeviceMemory *bufferMemory, VkMemoryPropertyFlags memoryPropertyFlags)
|
||||||
|
{
|
||||||
|
VkBufferCreateInfo bufferCreateInfo = {};
|
||||||
|
bufferCreateInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
|
||||||
|
bufferCreateInfo.size = bufferSize;
|
||||||
|
bufferCreateInfo.usage = usageFlags;
|
||||||
|
bufferCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||||
|
|
||||||
|
ASSERT_VK(vkCreateBuffer(compute->device, &bufferCreateInfo, NULL, buffer))
|
||||||
|
|
||||||
|
VkMemoryRequirements bufferMemoryRequirements;
|
||||||
|
vkGetBufferMemoryRequirements(compute->device, *buffer, &bufferMemoryRequirements);
|
||||||
|
|
||||||
|
VkMemoryAllocateInfo memoryAllocateInfo = {};
|
||||||
|
memoryAllocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
|
||||||
|
memoryAllocateInfo.allocationSize = bufferMemoryRequirements.size;
|
||||||
|
memoryAllocateInfo.memoryTypeIndex = findMemoryType(compute,
|
||||||
|
bufferMemoryRequirements.memoryTypeBits,
|
||||||
memoryPropertyFlags);
|
memoryPropertyFlags);
|
||||||
|
|
||||||
ASSERT_VK(vkAllocateMemory(compute->device, &particleMemoryAllocateInfo, NULL, bufferMemory))
|
ASSERT_VK(vkAllocateMemory(compute->device, &memoryAllocateInfo, NULL, bufferMemory))
|
||||||
|
|
||||||
ASSERT_VK(vkBindBufferMemory(compute->device, *buffer, *bufferMemory, 0))
|
ASSERT_VK(vkBindBufferMemory(compute->device, *buffer, *bufferMemory, 0))
|
||||||
}
|
}
|
||||||
|
|
||||||
void createComputeBuffers(Compute *compute)
|
void createComputeBuffers(Compute *compute)
|
||||||
{
|
{
|
||||||
// Particle Buffer
|
|
||||||
createComputeBuffer(compute, compute->particleBufferSize,
|
|
||||||
VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
|
|
||||||
&(compute->particleBuffer),
|
|
||||||
&(compute->particleBufferMemory), VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
|
|
||||||
|
|
||||||
// dt Uniform Buffer
|
// dt Uniform Buffer
|
||||||
createComputeBuffer(compute, compute->dtUniformBufferSize, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
|
createComputeBuffer(compute, compute->dtUniformBufferSize, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
|
||||||
&(compute->dtUniformBuffer),
|
&(compute->dtUniformBuffer),
|
||||||
@ -350,7 +393,7 @@ void mapBufferMemory(Compute *compute, VkDeviceMemory memory, void *inputData, u
|
|||||||
|
|
||||||
void copyBuffer(Compute *compute, VkBuffer src, VkBuffer dst, VkDeviceSize size)
|
void copyBuffer(Compute *compute, VkBuffer src, VkBuffer dst, VkDeviceSize size)
|
||||||
{
|
{
|
||||||
uint32_t queueFamilyIndex = getQueueFamilyIndex(compute, VK_QUEUE_TRANSFER_BIT);
|
uint32_t queueFamilyIndex = getQueueFamilyIndex(compute->physicalDevice, VK_QUEUE_TRANSFER_BIT, 0);
|
||||||
|
|
||||||
VkCommandPoolCreateInfo commandPoolCreateInfo = {};
|
VkCommandPoolCreateInfo commandPoolCreateInfo = {};
|
||||||
commandPoolCreateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
|
commandPoolCreateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
|
||||||
@ -418,7 +461,7 @@ void fillComputeBuffers(Compute *compute, float *particles, Dt *dtData, StaticIn
|
|||||||
fillComputeBuffer(compute, compute->staticInUniformBuffer, staticInData, compute->staticInUniformBufferSize);
|
fillComputeBuffer(compute, compute->staticInUniformBuffer, staticInData, compute->staticInUniformBufferSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
void createComputeCommandBuffer(Compute *compute)
|
void createComputeCommandBuffer(Compute *compute, Graphics *graphics)
|
||||||
{
|
{
|
||||||
VkCommandPoolCreateInfo commandPoolCreateInfo = {};
|
VkCommandPoolCreateInfo commandPoolCreateInfo = {};
|
||||||
commandPoolCreateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
|
commandPoolCreateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
|
||||||
@ -461,29 +504,12 @@ void createSemaphore(VkDevice device, VkSemaphore *semaphore)
|
|||||||
ASSERT_VK(vkCreateSemaphore(device, &semaphoreCreateInfo, NULL, semaphore));
|
ASSERT_VK(vkCreateSemaphore(device, &semaphoreCreateInfo, NULL, semaphore));
|
||||||
}
|
}
|
||||||
|
|
||||||
void runComputeCommandBuffer(Compute *compute)
|
|
||||||
{
|
|
||||||
VkSubmitInfo submitInfo = {};
|
|
||||||
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
|
||||||
submitInfo.commandBufferCount = 1;
|
|
||||||
submitInfo.pCommandBuffers = &(compute->commandBuffer);
|
|
||||||
|
|
||||||
VkFence fence;
|
|
||||||
VkFenceCreateInfo fenceCreateInfo = {};
|
|
||||||
fenceCreateInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
|
|
||||||
fenceCreateInfo.flags = 0;
|
|
||||||
|
|
||||||
ASSERT_VK(vkCreateFence(compute->device, &fenceCreateInfo, NULL, &fence))
|
|
||||||
|
|
||||||
ASSERT_VK(vkQueueSubmit(compute->queue, 1, &submitInfo, fence))
|
|
||||||
|
|
||||||
ASSERT_VK(vkWaitForFences(compute->device, 1, &fence, VK_TRUE, UINT64_MAX))
|
|
||||||
|
|
||||||
vkDestroyFence(compute->device, fence, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
void shutdownComputeVulkan(Compute *compute)
|
void shutdownComputeVulkan(Compute *compute)
|
||||||
{
|
{
|
||||||
|
vkDeviceWaitIdle(compute->device);
|
||||||
|
|
||||||
|
vkDestroySemaphore(compute->device, compute->semaphore, NULL);
|
||||||
|
|
||||||
vkFreeMemory(compute->device, compute->particleBufferMemory, NULL);
|
vkFreeMemory(compute->device, compute->particleBufferMemory, NULL);
|
||||||
vkFreeMemory(compute->device, compute->dtUniformBufferMemory, NULL);
|
vkFreeMemory(compute->device, compute->dtUniformBufferMemory, NULL);
|
||||||
vkFreeMemory(compute->device, compute->staticInUniformBufferMemory, NULL);
|
vkFreeMemory(compute->device, compute->staticInUniformBufferMemory, NULL);
|
||||||
@ -531,7 +557,7 @@ void createSwapchain(Graphics *graphics)
|
|||||||
}
|
}
|
||||||
|
|
||||||
VkExtent2D imageExtent = { WIDTH, HEIGHT };
|
VkExtent2D imageExtent = { WIDTH, HEIGHT };
|
||||||
VkSwapchainCreateInfoKHR swapChainCreateInfo;
|
VkSwapchainCreateInfoKHR swapChainCreateInfo = {};
|
||||||
swapChainCreateInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
|
swapChainCreateInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
|
||||||
swapChainCreateInfo.surface = graphics->surface;
|
swapChainCreateInfo.surface = graphics->surface;
|
||||||
swapChainCreateInfo.minImageCount = 1;
|
swapChainCreateInfo.minImageCount = 1;
|
||||||
@ -543,7 +569,7 @@ void createSwapchain(Graphics *graphics)
|
|||||||
swapChainCreateInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
swapChainCreateInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||||
swapChainCreateInfo.preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
|
swapChainCreateInfo.preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
|
||||||
swapChainCreateInfo.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
|
swapChainCreateInfo.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
|
||||||
swapChainCreateInfo.presentMode = VK_PRESENT_MODE_FIFO_KHR;
|
swapChainCreateInfo.presentMode = VK_PRESENT_MODE_IMMEDIATE_KHR;
|
||||||
swapChainCreateInfo.clipped = VK_FALSE;
|
swapChainCreateInfo.clipped = VK_FALSE;
|
||||||
swapChainCreateInfo.oldSwapchain = VK_NULL_HANDLE;
|
swapChainCreateInfo.oldSwapchain = VK_NULL_HANDLE;
|
||||||
|
|
||||||
@ -557,7 +583,7 @@ void createSwapchain(Graphics *graphics)
|
|||||||
|
|
||||||
for (int i = 0; i < graphics->imageViewsSize; i++)
|
for (int i = 0; i < graphics->imageViewsSize; i++)
|
||||||
{
|
{
|
||||||
VkImageViewCreateInfo imageViewInfo;
|
VkImageViewCreateInfo imageViewInfo = {};
|
||||||
VkComponentMapping componentMapping = {
|
VkComponentMapping componentMapping = {
|
||||||
VK_COMPONENT_SWIZZLE_IDENTITY,
|
VK_COMPONENT_SWIZZLE_IDENTITY,
|
||||||
VK_COMPONENT_SWIZZLE_IDENTITY,
|
VK_COMPONENT_SWIZZLE_IDENTITY,
|
||||||
@ -590,12 +616,41 @@ void createShaderStageInfo(VkPipelineShaderStageCreateInfo *shaderStageCreateInf
|
|||||||
|
|
||||||
void createGraphicsPipeline(Graphics *graphics)
|
void createGraphicsPipeline(Graphics *graphics)
|
||||||
{
|
{
|
||||||
|
VkVertexInputBindingDescription vertexInputBindingDescription;
|
||||||
|
vertexInputBindingDescription.binding = 0;
|
||||||
|
vertexInputBindingDescription.stride = PARTICLE_SIZE;
|
||||||
|
vertexInputBindingDescription.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
|
||||||
|
|
||||||
|
VkVertexInputAttributeDescription positionVertexInputAttributeDescription;
|
||||||
|
positionVertexInputAttributeDescription.binding = 0;
|
||||||
|
positionVertexInputAttributeDescription.location = 0;
|
||||||
|
positionVertexInputAttributeDescription.format = VK_FORMAT_R32G32_SFLOAT;
|
||||||
|
positionVertexInputAttributeDescription.offset = 0;
|
||||||
|
|
||||||
|
VkVertexInputAttributeDescription colInVertexInputAttributeDescription;
|
||||||
|
colInVertexInputAttributeDescription.binding = 0;
|
||||||
|
colInVertexInputAttributeDescription.location = 1;
|
||||||
|
colInVertexInputAttributeDescription.format = VK_FORMAT_R32G32_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/vert.spv", &(graphics->vertexShaderModule));
|
||||||
createShaderModule(graphics->device, "./vulkan/frag.spv", &(graphics->fragmentShaderModule));
|
createShaderModule(graphics->device, "./vulkan/frag.spv", &(graphics->fragmentShaderModule));
|
||||||
|
|
||||||
VkPipelineShaderStageCreateInfo vertexShaderStageInfo;
|
VkPipelineShaderStageCreateInfo vertexShaderStageInfo = {};
|
||||||
createShaderStageInfo(&vertexShaderStageInfo, VK_SHADER_STAGE_VERTEX_BIT, graphics->vertexShaderModule);
|
createShaderStageInfo(&vertexShaderStageInfo, VK_SHADER_STAGE_VERTEX_BIT, graphics->vertexShaderModule);
|
||||||
VkPipelineShaderStageCreateInfo fragmentShaderStageInfo;
|
VkPipelineShaderStageCreateInfo fragmentShaderStageInfo = {};
|
||||||
createShaderStageInfo(&fragmentShaderStageInfo, VK_SHADER_STAGE_FRAGMENT_BIT, graphics->fragmentShaderModule);
|
createShaderStageInfo(&fragmentShaderStageInfo, VK_SHADER_STAGE_FRAGMENT_BIT, graphics->fragmentShaderModule);
|
||||||
|
|
||||||
VkPipelineShaderStageCreateInfo shaderStages[] = {
|
VkPipelineShaderStageCreateInfo shaderStages[] = {
|
||||||
@ -603,15 +658,12 @@ void createGraphicsPipeline(Graphics *graphics)
|
|||||||
fragmentShaderStageInfo
|
fragmentShaderStageInfo
|
||||||
};
|
};
|
||||||
|
|
||||||
VkPipelineVertexInputStateCreateInfo vertexInputStateInfo;
|
VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateInfo = {};
|
||||||
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.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
|
||||||
inputAssemblyStateInfo.topology = VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
|
inputAssemblyStateInfo.topology = VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
|
||||||
inputAssemblyStateInfo.primitiveRestartEnable = VK_FALSE;
|
inputAssemblyStateInfo.primitiveRestartEnable = VK_FALSE;
|
||||||
|
|
||||||
VkViewport viewport;
|
VkViewport viewport = {};
|
||||||
viewport.x = 0.0f;
|
viewport.x = 0.0f;
|
||||||
viewport.y = 0.0f;
|
viewport.y = 0.0f;
|
||||||
viewport.width = WIDTH;
|
viewport.width = WIDTH;
|
||||||
@ -621,18 +673,18 @@ void createGraphicsPipeline(Graphics *graphics)
|
|||||||
|
|
||||||
VkRect2D scissor = { {0, 0}, {WIDTH, HEIGHT} };
|
VkRect2D scissor = { {0, 0}, {WIDTH, HEIGHT} };
|
||||||
|
|
||||||
VkPipelineViewportStateCreateInfo viewportStateInfo;
|
VkPipelineViewportStateCreateInfo viewportStateInfo = {};
|
||||||
viewportStateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
|
viewportStateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
|
||||||
viewportStateInfo.viewportCount = 1;
|
viewportStateInfo.viewportCount = 1;
|
||||||
viewportStateInfo.pViewports = &viewport;
|
viewportStateInfo.pViewports = &viewport;
|
||||||
viewportStateInfo.scissorCount = 1;
|
viewportStateInfo.scissorCount = 1;
|
||||||
viewportStateInfo.pScissors = &scissor;
|
viewportStateInfo.pScissors = &scissor;
|
||||||
|
|
||||||
VkPipelineRasterizationStateCreateInfo rasterizationStateInfo;
|
VkPipelineRasterizationStateCreateInfo rasterizationStateInfo = {};
|
||||||
rasterizationStateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
|
rasterizationStateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
|
||||||
rasterizationStateInfo.depthClampEnable = VK_FALSE;
|
rasterizationStateInfo.depthClampEnable = VK_FALSE;
|
||||||
rasterizationStateInfo.rasterizerDiscardEnable = VK_FALSE;
|
rasterizationStateInfo.rasterizerDiscardEnable = VK_FALSE;
|
||||||
rasterizationStateInfo.polygonMode = VK_POLYGON_MODE_POINT;
|
rasterizationStateInfo.polygonMode = VK_POLYGON_MODE_FILL;
|
||||||
rasterizationStateInfo.cullMode = VK_CULL_MODE_BACK_BIT;
|
rasterizationStateInfo.cullMode = VK_CULL_MODE_BACK_BIT;
|
||||||
rasterizationStateInfo.frontFace = VK_FRONT_FACE_CLOCKWISE;
|
rasterizationStateInfo.frontFace = VK_FRONT_FACE_CLOCKWISE;
|
||||||
rasterizationStateInfo.depthBiasEnable = VK_FALSE;
|
rasterizationStateInfo.depthBiasEnable = VK_FALSE;
|
||||||
@ -641,7 +693,7 @@ void createGraphicsPipeline(Graphics *graphics)
|
|||||||
rasterizationStateInfo.depthBiasSlopeFactor = 0.0f;
|
rasterizationStateInfo.depthBiasSlopeFactor = 0.0f;
|
||||||
rasterizationStateInfo.lineWidth = 1.0f;
|
rasterizationStateInfo.lineWidth = 1.0f;
|
||||||
|
|
||||||
VkPipelineMultisampleStateCreateInfo multisampleStateInfo;
|
VkPipelineMultisampleStateCreateInfo multisampleStateInfo = {};
|
||||||
multisampleStateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
|
multisampleStateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
|
||||||
multisampleStateInfo.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
|
multisampleStateInfo.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
|
||||||
multisampleStateInfo.sampleShadingEnable = VK_FALSE;
|
multisampleStateInfo.sampleShadingEnable = VK_FALSE;
|
||||||
@ -649,7 +701,7 @@ void createGraphicsPipeline(Graphics *graphics)
|
|||||||
multisampleStateInfo.alphaToCoverageEnable = VK_FALSE;
|
multisampleStateInfo.alphaToCoverageEnable = VK_FALSE;
|
||||||
multisampleStateInfo.alphaToOneEnable = VK_FALSE;
|
multisampleStateInfo.alphaToOneEnable = VK_FALSE;
|
||||||
|
|
||||||
VkPipelineColorBlendAttachmentState colorBlendAttachmentState;
|
VkPipelineColorBlendAttachmentState colorBlendAttachmentState = {};
|
||||||
colorBlendAttachmentState.blendEnable = VK_FALSE;
|
colorBlendAttachmentState.blendEnable = VK_FALSE;
|
||||||
colorBlendAttachmentState.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
|
colorBlendAttachmentState.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
|
||||||
colorBlendAttachmentState.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
|
colorBlendAttachmentState.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
|
||||||
@ -659,7 +711,7 @@ void createGraphicsPipeline(Graphics *graphics)
|
|||||||
colorBlendAttachmentState.alphaBlendOp = VK_BLEND_OP_ADD;
|
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;
|
colorBlendAttachmentState.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
|
||||||
|
|
||||||
VkPipelineColorBlendStateCreateInfo colorBlendStateInfo;
|
VkPipelineColorBlendStateCreateInfo colorBlendStateInfo = {};
|
||||||
colorBlendStateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
|
colorBlendStateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
|
||||||
colorBlendStateInfo.logicOpEnable = VK_FALSE;
|
colorBlendStateInfo.logicOpEnable = VK_FALSE;
|
||||||
colorBlendStateInfo.logicOp = VK_LOGIC_OP_NO_OP;
|
colorBlendStateInfo.logicOp = VK_LOGIC_OP_NO_OP;
|
||||||
@ -670,41 +722,52 @@ void createGraphicsPipeline(Graphics *graphics)
|
|||||||
colorBlendStateInfo.blendConstants[2] = 0.0f;
|
colorBlendStateInfo.blendConstants[2] = 0.0f;
|
||||||
colorBlendStateInfo.blendConstants[3] = 0.0f;
|
colorBlendStateInfo.blendConstants[3] = 0.0f;
|
||||||
|
|
||||||
VkPipelineLayoutCreateInfo layoutInfo;
|
VkPipelineLayoutCreateInfo layoutInfo = {};
|
||||||
layoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
|
layoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
|
||||||
|
|
||||||
ASSERT_VK(vkCreatePipelineLayout(graphics->device, &layoutInfo, NULL, &(graphics->pipelineLayout)))
|
ASSERT_VK(vkCreatePipelineLayout(graphics->device, &layoutInfo, NULL, &(graphics->pipelineLayout)))
|
||||||
|
|
||||||
VkAttachmentDescription attachmentDescription;
|
VkAttachmentDescription attachmentDescription = {};
|
||||||
attachmentDescription.format = VK_FORMAT_B8G8R8A8_UNORM;
|
attachmentDescription.format = VK_FORMAT_B8G8R8A8_UNORM;
|
||||||
attachmentDescription.samples = VK_SAMPLE_COUNT_1_BIT;
|
attachmentDescription.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||||
attachmentDescription.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
attachmentDescription.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||||
attachmentDescription.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
attachmentDescription.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||||
attachmentDescription.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
attachmentDescription.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||||
attachmentDescription.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
attachmentDescription.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
||||||
attachmentDescription.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
attachmentDescription.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||||
attachmentDescription.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
|
attachmentDescription.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
|
||||||
|
|
||||||
VkAttachmentReference attachmentReference;
|
VkAttachmentReference attachmentReference = {};
|
||||||
attachmentReference.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
attachmentReference.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||||
|
|
||||||
VkSubpassDescription subpassDescription;
|
VkSubpassDescription subpassDescription = {};
|
||||||
subpassDescription.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
|
subpassDescription.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
|
||||||
subpassDescription.colorAttachmentCount = 1;
|
subpassDescription.colorAttachmentCount = 1;
|
||||||
subpassDescription.pColorAttachments = &attachmentReference;
|
subpassDescription.pColorAttachments = &attachmentReference;
|
||||||
|
|
||||||
VkRenderPassCreateInfo renderPassInfo;
|
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.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
|
||||||
renderPassInfo.attachmentCount = 1;
|
renderPassInfo.attachmentCount = 1;
|
||||||
renderPassInfo.pAttachments = &attachmentDescription;
|
renderPassInfo.pAttachments = &attachmentDescription;
|
||||||
renderPassInfo.subpassCount = 1;
|
renderPassInfo.subpassCount = 1;
|
||||||
renderPassInfo.pSubpasses = &subpassDescription;
|
renderPassInfo.pSubpasses = &subpassDescription;
|
||||||
|
renderPassInfo.dependencyCount = 1;
|
||||||
|
renderPassInfo.pDependencies = &subpassDependency;
|
||||||
|
|
||||||
|
|
||||||
ASSERT_VK(vkCreateRenderPass(graphics->device, &renderPassInfo, NULL, &(graphics->renderPass)))
|
ASSERT_VK(vkCreateRenderPass(graphics->device, &renderPassInfo, NULL, &(graphics->renderPass)))
|
||||||
|
|
||||||
VkGraphicsPipelineCreateInfo graphicsPipelineInfo;
|
VkGraphicsPipelineCreateInfo graphicsPipelineInfo = {};
|
||||||
graphicsPipelineInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
|
graphicsPipelineInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
|
||||||
graphicsPipelineInfo.stageCount = 3;
|
graphicsPipelineInfo.stageCount = 2;
|
||||||
graphicsPipelineInfo.pStages = shaderStages;
|
graphicsPipelineInfo.pStages = shaderStages;
|
||||||
graphicsPipelineInfo.pVertexInputState = &vertexInputStateInfo;
|
graphicsPipelineInfo.pVertexInputState = &vertexInputStateInfo;
|
||||||
graphicsPipelineInfo.pInputAssemblyState = &inputAssemblyStateInfo;
|
graphicsPipelineInfo.pInputAssemblyState = &inputAssemblyStateInfo;
|
||||||
@ -720,7 +783,106 @@ void createGraphicsPipeline(Graphics *graphics)
|
|||||||
ASSERT_VK(vkCreateGraphicsPipelines(graphics->device, VK_NULL_HANDLE, 1, &graphicsPipelineInfo, NULL, &(graphics->pipeline)))
|
ASSERT_VK(vkCreateGraphicsPipelines(graphics->device, VK_NULL_HANDLE, 1, &graphicsPipelineInfo, NULL, &(graphics->pipeline)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void createFramebuffer(Graphics *graphics)
|
||||||
|
{
|
||||||
|
graphics->framebuffers = malloc(graphics->imageViewsSize * sizeof(VkFramebuffer));
|
||||||
|
for (int i = 0; i < graphics->imageViewsSize; ++i)
|
||||||
|
{
|
||||||
|
VkFramebufferCreateInfo framebufferInfo = {};
|
||||||
|
framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
|
||||||
|
framebufferInfo.renderPass = graphics->renderPass;
|
||||||
|
framebufferInfo.attachmentCount = 1;
|
||||||
|
framebufferInfo.pAttachments = &(graphics->imageViews[i]);
|
||||||
|
framebufferInfo.width = WIDTH;
|
||||||
|
framebufferInfo.height = HEIGHT;
|
||||||
|
framebufferInfo.layers = 1;
|
||||||
|
|
||||||
|
ASSERT_VK(vkCreateFramebuffer(graphics->device, &framebufferInfo, NULL, &(graphics->framebuffers[i])))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void createGraphicsCommandBuffers(Graphics *graphics)
|
void createGraphicsCommandBuffers(Graphics *graphics)
|
||||||
{
|
{
|
||||||
|
VkCommandPoolCreateInfo commandPoolInfo = {};
|
||||||
|
commandPoolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
|
||||||
|
commandPoolInfo.queueFamilyIndex = graphics->queueFamilyIndex;
|
||||||
|
|
||||||
|
ASSERT_VK(vkCreateCommandPool(graphics->device, &commandPoolInfo, NULL, &(graphics->commandPool)))
|
||||||
|
|
||||||
|
VkCommandBufferAllocateInfo commandBufferAllocateInfo = {};
|
||||||
|
commandBufferAllocateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
|
||||||
|
commandBufferAllocateInfo.commandPool = graphics->commandPool;
|
||||||
|
commandBufferAllocateInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
|
||||||
|
commandBufferAllocateInfo.commandBufferCount = graphics->imageViewsSize;
|
||||||
|
|
||||||
|
graphics->commandBuffers = malloc(graphics->imageViewsSize * sizeof(VkCommandBuffer));
|
||||||
|
|
||||||
|
ASSERT_VK(vkAllocateCommandBuffers(graphics->device, &commandBufferAllocateInfo, graphics->commandBuffers))
|
||||||
|
|
||||||
|
VkCommandBufferBeginInfo commandBufferBeginInfo = {};
|
||||||
|
commandBufferBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
|
||||||
|
commandBufferBeginInfo.flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT;
|
||||||
|
|
||||||
|
VkRect2D renderArea = { {0, 0}, {WIDTH, HEIGHT} };
|
||||||
|
VkClearValue clearValue = {0, 0, 0, 1};
|
||||||
|
|
||||||
|
for (int i = 0; i < graphics->imageViewsSize; i++)
|
||||||
|
{
|
||||||
|
ASSERT_VK(vkBeginCommandBuffer(graphics->commandBuffers[i], &commandBufferBeginInfo))
|
||||||
|
|
||||||
|
VkRenderPassBeginInfo renderPassBeginInfo = {};
|
||||||
|
renderPassBeginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
|
||||||
|
renderPassBeginInfo.renderPass = graphics->renderPass;
|
||||||
|
renderPassBeginInfo.framebuffer = graphics->framebuffers[i];
|
||||||
|
renderPassBeginInfo.renderArea = renderArea;
|
||||||
|
renderPassBeginInfo.clearValueCount = 1;
|
||||||
|
renderPassBeginInfo.pClearValues = &clearValue;
|
||||||
|
|
||||||
|
vkCmdBeginRenderPass(graphics->commandBuffers[i], &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
|
||||||
|
|
||||||
|
vkCmdBindPipeline(graphics->commandBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, graphics->pipeline);
|
||||||
|
|
||||||
|
VkDeviceSize offsets[1] = { 0 };
|
||||||
|
vkCmdBindVertexBuffers(graphics->commandBuffers[i], 0, 1, &(graphics->particleBuffer), offsets);
|
||||||
|
|
||||||
|
vkCmdDraw(graphics->commandBuffers[i], PARTICLE_AMOUNT, 1, 0, 0);
|
||||||
|
|
||||||
|
vkCmdEndRenderPass(graphics->commandBuffers[i]);
|
||||||
|
|
||||||
|
ASSERT_VK(vkEndCommandBuffer(graphics->commandBuffers[i]))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void shutdownGraphicsVulkan(Graphics *graphics)
|
||||||
|
{
|
||||||
|
vkDeviceWaitIdle(graphics->device);
|
||||||
|
|
||||||
|
for (int i = 0; i < graphics->imageViewsSize; ++i)
|
||||||
|
{
|
||||||
|
vkDestroyFramebuffer(graphics->device, graphics->framebuffers[i], NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
vkDestroyCommandPool(graphics->device, graphics->commandPool, NULL);
|
||||||
|
|
||||||
|
vkDestroySemaphore(graphics->device, graphics->semaphore, NULL);
|
||||||
|
vkDestroySemaphore(graphics->device, graphics->renderComplete, NULL);
|
||||||
|
vkDestroySemaphore(graphics->device, graphics->presentComplete, NULL);
|
||||||
|
|
||||||
|
vkDestroyPipelineLayout(graphics->device, graphics->pipelineLayout, NULL);
|
||||||
|
|
||||||
|
vkDestroyRenderPass(graphics->device, graphics->renderPass, NULL);
|
||||||
|
|
||||||
|
vkDestroyPipeline(graphics->device, graphics->pipeline, NULL);
|
||||||
|
|
||||||
|
vkDestroyShaderModule(graphics->device, graphics->fragmentShaderModule, NULL);
|
||||||
|
vkDestroyShaderModule(graphics->device, graphics->vertexShaderModule, NULL);
|
||||||
|
|
||||||
|
for (int i = 0; i < graphics->imageViewsSize; ++i)
|
||||||
|
{
|
||||||
|
vkDestroyImageView(graphics->device, graphics->imageViews[i], NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
vkDestroySwapchainKHR(graphics->device, graphics->swapChain, NULL);
|
||||||
|
|
||||||
|
vkDestroySurfaceKHR(graphics->instance, graphics->surface, NULL);
|
||||||
}
|
}
|
@ -14,7 +14,7 @@
|
|||||||
#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 100
|
#define PARTICLE_AMOUNT 1000000
|
||||||
#define PARTICLE_SIZE (3 * sizeof(vector3f) + sizeof(float))
|
#define PARTICLE_SIZE (3 * sizeof(vector3f) + sizeof(float))
|
||||||
#define WORKGROUP_SIZE_X 1024
|
#define WORKGROUP_SIZE_X 1024
|
||||||
#define WORKGROUP_SIZE_Y 1
|
#define WORKGROUP_SIZE_Y 1
|
||||||
@ -92,7 +92,7 @@ typedef struct graphics {
|
|||||||
VkShaderModule fragmentShaderModule;
|
VkShaderModule fragmentShaderModule;
|
||||||
|
|
||||||
VkCommandPool commandPool;
|
VkCommandPool commandPool;
|
||||||
VkCommandBuffer commandBuffer;
|
VkCommandBuffer *commandBuffers;
|
||||||
|
|
||||||
VkBuffer particleBuffer;
|
VkBuffer particleBuffer;
|
||||||
uint32_t particleBufferSize;
|
uint32_t particleBufferSize;
|
||||||
@ -100,6 +100,8 @@ typedef struct graphics {
|
|||||||
VkQueue queue;
|
VkQueue queue;
|
||||||
uint32_t queueFamilyIndex;
|
uint32_t queueFamilyIndex;
|
||||||
|
|
||||||
|
VkSemaphore renderComplete;
|
||||||
|
VkSemaphore presentComplete;
|
||||||
VkSemaphore semaphore;
|
VkSemaphore semaphore;
|
||||||
} Graphics;
|
} Graphics;
|
||||||
|
|
||||||
@ -117,10 +119,13 @@ typedef struct staticIn {
|
|||||||
// Shutdown
|
// Shutdown
|
||||||
void shutdownGLFW(GLFWwindow *window);
|
void shutdownGLFW(GLFWwindow *window);
|
||||||
void shutdownComputeVulkan(Compute *compute);
|
void shutdownComputeVulkan(Compute *compute);
|
||||||
|
void shutdownGraphicsVulkan(Graphics *graphics);
|
||||||
|
|
||||||
|
// General
|
||||||
void createInstance(Compute *compute, Graphics *graphics);
|
void createInstance(Compute *compute, Graphics *graphics);
|
||||||
void findPhysicalDevice(Compute *compute, Graphics *graphics);
|
void findPhysicalDevice(Compute *compute, Graphics *graphics);
|
||||||
void createDevice(Compute *compute, Graphics *graphics);
|
void createDevice(Compute *compute, Graphics *graphics);
|
||||||
|
void createParticleBuffer(Compute *compute, Graphics *graphics);
|
||||||
|
|
||||||
// Compute
|
// Compute
|
||||||
void createComputeBuffers(Compute *compute);
|
void createComputeBuffers(Compute *compute);
|
||||||
@ -128,13 +133,13 @@ void createComputeDescriptorSetLayouts(Compute *compute);
|
|||||||
void createComputeDescriptorSets(Compute *compute);
|
void createComputeDescriptorSets(Compute *compute);
|
||||||
void createComputePipeline(Compute *compute);
|
void createComputePipeline(Compute *compute);
|
||||||
void fillComputeBuffers(Compute *compute, float *particles, Dt *dtData, StaticIn *staticInData);
|
void fillComputeBuffers(Compute *compute, float *particles, Dt *dtData, StaticIn *staticInData);
|
||||||
void createComputeCommandBuffer(Compute *compute);
|
void createComputeCommandBuffer(Compute *compute, Graphics *graphics);
|
||||||
void runComputeCommandBuffer(Compute *compute);
|
|
||||||
|
|
||||||
// Graphics
|
// Graphics
|
||||||
void createGraphicsSurface(Graphics *graphics, GLFWwindow *window);
|
void createGraphicsSurface(Graphics *graphics, GLFWwindow *window);
|
||||||
void createSwapchain(Graphics *graphics);
|
void createSwapchain(Graphics *graphics);
|
||||||
void createGraphicsPipeline(Graphics *graphics);
|
void createGraphicsPipeline(Graphics *graphics);
|
||||||
|
void createFramebuffer(Graphics *graphics);
|
||||||
void createGraphicsCommandBuffers(Graphics *graphics);
|
void createGraphicsCommandBuffers(Graphics *graphics);
|
||||||
|
|
||||||
// ELse
|
// ELse
|
||||||
|
@ -40,6 +40,7 @@ int main()
|
|||||||
createInstance(&compute, &graphics);
|
createInstance(&compute, &graphics);
|
||||||
findPhysicalDevice(&compute, &graphics);
|
findPhysicalDevice(&compute, &graphics);
|
||||||
createDevice(&compute, &graphics);
|
createDevice(&compute, &graphics);
|
||||||
|
createParticleBuffer(&compute, &graphics);
|
||||||
|
|
||||||
// Compute
|
// Compute
|
||||||
createComputeBuffers(&compute);
|
createComputeBuffers(&compute);
|
||||||
@ -47,38 +48,99 @@ int main()
|
|||||||
createComputeDescriptorSets(&compute);
|
createComputeDescriptorSets(&compute);
|
||||||
createComputePipeline(&compute);
|
createComputePipeline(&compute);
|
||||||
fillComputeBuffers(&compute, particles, &dt, &staticIn);
|
fillComputeBuffers(&compute, particles, &dt, &staticIn);
|
||||||
createComputeCommandBuffer(&compute);
|
|
||||||
createSemaphore(compute.device, &(compute.semaphore));
|
createSemaphore(compute.device, &(compute.semaphore));
|
||||||
|
VkSubmitInfo submitInfo = {};
|
||||||
|
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
||||||
|
submitInfo.signalSemaphoreCount = 1;
|
||||||
|
submitInfo.pSignalSemaphores = &compute.semaphore;
|
||||||
|
ASSERT_VK(vkQueueSubmit(compute.queue, 1, &submitInfo, VK_NULL_HANDLE));
|
||||||
|
ASSERT_VK(vkQueueWaitIdle(compute.queue));
|
||||||
|
|
||||||
|
createComputeCommandBuffer(&compute, &graphics);
|
||||||
|
|
||||||
// Graphics
|
// Graphics
|
||||||
|
graphics.particleBuffer = compute.particleBuffer;
|
||||||
|
graphics.particleBufferSize = compute.particleBufferSize;
|
||||||
createGraphicsSurface(&graphics, window);
|
createGraphicsSurface(&graphics, window);
|
||||||
createSwapchain(&graphics);
|
createSwapchain(&graphics);
|
||||||
createGraphicsPipeline(&graphics);
|
createGraphicsPipeline(&graphics);
|
||||||
|
createFramebuffer(&graphics);
|
||||||
createGraphicsCommandBuffers(&graphics);
|
createGraphicsCommandBuffers(&graphics);
|
||||||
|
createSemaphore(graphics.device, &(graphics.presentComplete));
|
||||||
|
createSemaphore(graphics.device, &(graphics.renderComplete));
|
||||||
createSemaphore(graphics.device, &(graphics.semaphore));
|
createSemaphore(graphics.device, &(graphics.semaphore));
|
||||||
|
|
||||||
|
|
||||||
/************* RENDER LOOP *************/
|
/************* RENDER LOOP *************/
|
||||||
|
// Graphics preparation
|
||||||
|
VkPipelineStageFlags graphicsWaitStageMasks[] = {
|
||||||
|
VK_PIPELINE_STAGE_VERTEX_INPUT_BIT,
|
||||||
|
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
|
||||||
|
};
|
||||||
|
VkSemaphore graphicsWaitSemaphores[] = { compute.semaphore, graphics.presentComplete };
|
||||||
|
VkSemaphore graphicsSignalSemaphores[] = { graphics.semaphore, graphics.renderComplete };
|
||||||
|
|
||||||
|
VkSubmitInfo graphicsSubmitInfo = {};
|
||||||
|
graphicsSubmitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
||||||
|
graphicsSubmitInfo.commandBufferCount = 1;
|
||||||
|
graphicsSubmitInfo.waitSemaphoreCount = 2;
|
||||||
|
graphicsSubmitInfo.pWaitSemaphores = graphicsWaitSemaphores;
|
||||||
|
graphicsSubmitInfo.pWaitDstStageMask = graphicsWaitStageMasks;
|
||||||
|
graphicsSubmitInfo.signalSemaphoreCount = 2;
|
||||||
|
graphicsSubmitInfo.pSignalSemaphores = graphicsSignalSemaphores;
|
||||||
|
|
||||||
|
VkPresentInfoKHR graphicsPresentInfo = {};
|
||||||
|
graphicsPresentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
|
||||||
|
graphicsPresentInfo.waitSemaphoreCount = 1;
|
||||||
|
graphicsPresentInfo.pWaitSemaphores = &(graphics.renderComplete);
|
||||||
|
graphicsPresentInfo.swapchainCount = 1;
|
||||||
|
graphicsPresentInfo.pSwapchains = &(graphics.swapChain);
|
||||||
|
|
||||||
|
|
||||||
|
// Compute preparation
|
||||||
|
VkPipelineStageFlags computeWaitStageMask = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
|
||||||
|
|
||||||
|
VkSubmitInfo computeSubmitInfo = {};
|
||||||
|
computeSubmitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
||||||
|
computeSubmitInfo.commandBufferCount = 1;
|
||||||
|
computeSubmitInfo.pCommandBuffers = &(compute.commandBuffer);
|
||||||
|
computeSubmitInfo.waitSemaphoreCount = 1;
|
||||||
|
computeSubmitInfo.pWaitSemaphores = &graphics.semaphore;
|
||||||
|
computeSubmitInfo.pWaitDstStageMask = &computeWaitStageMask;
|
||||||
|
computeSubmitInfo.signalSemaphoreCount = 1;
|
||||||
|
computeSubmitInfo.pSignalSemaphores = &compute.semaphore;
|
||||||
|
|
||||||
|
// Loop
|
||||||
double time, tLast = 0;
|
double time, tLast = 0;
|
||||||
Dt tFrame = {};
|
Dt tFrame = {};
|
||||||
|
uint32_t imageIndex;
|
||||||
while (!glfwWindowShouldClose(window))
|
while (!glfwWindowShouldClose(window))
|
||||||
{
|
{
|
||||||
time = glfwGetTime();
|
time = glfwGetTime();
|
||||||
tFrame.dt = (float) (time - tLast);
|
tFrame.dt = (float) (time - tLast);
|
||||||
tLast = time;
|
tLast = time;
|
||||||
|
|
||||||
// Update dt
|
/*** RENDER ***/
|
||||||
mapBufferMemory(&compute, compute.dtUniformBufferMemory, &tFrame, sizeof(Dt));
|
ASSERT_VK(vkAcquireNextImageKHR(graphics.device, graphics.swapChain, UINT64_MAX, graphics.presentComplete, VK_NULL_HANDLE, &imageIndex))
|
||||||
|
|
||||||
|
graphicsSubmitInfo.pCommandBuffers = &(graphics.commandBuffers[imageIndex]);
|
||||||
|
ASSERT_VK(vkQueueSubmit(graphics.queue, 1, &graphicsSubmitInfo, VK_NULL_HANDLE))
|
||||||
|
|
||||||
|
graphicsPresentInfo.pImageIndices = &imageIndex;
|
||||||
|
ASSERT_VK(vkQueuePresentKHR(graphics.queue, &graphicsPresentInfo))
|
||||||
|
|
||||||
/*** UPDATE ***/
|
/*** UPDATE ***/
|
||||||
runComputeCommandBuffer(&compute);
|
// Update dt
|
||||||
|
mapBufferMemory(&compute, compute.dtUniformBufferMemory, &tFrame, sizeof(Dt));
|
||||||
/*** RENDER ***/
|
ASSERT_VK(vkQueueSubmit(compute.queue, 1, &computeSubmitInfo, VK_NULL_HANDLE))
|
||||||
|
|
||||||
glfwPollEvents();
|
glfwPollEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
shutdownGraphicsVulkan(&graphics);
|
||||||
shutdownComputeVulkan(&compute);
|
shutdownComputeVulkan(&compute);
|
||||||
shutdownGLFW(window);
|
shutdownGLFW(window);
|
||||||
|
|
||||||
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
#include "initOpenGL.h"
|
#include "initOpenGL.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
#define PARTICLE_AMOUNT 10000
|
#define PARTICLE_AMOUNT 1000000
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
@ -13,6 +13,7 @@ int main()
|
|||||||
setErrorCallbackGL();
|
setErrorCallbackGL();
|
||||||
|
|
||||||
int width = WIDTH, height = HEIGHT;
|
int width = WIDTH, height = HEIGHT;
|
||||||
|
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
|
||||||
GLFWwindow *window = createGLFWWindow(WIDTH, HEIGHT, "Informatikprojekt - OpenGL");
|
GLFWwindow *window = createGLFWWindow(WIDTH, HEIGHT, "Informatikprojekt - OpenGL");
|
||||||
|
|
||||||
setCurrentContextGL(window);
|
setCurrentContextGL(window);
|
||||||
@ -72,7 +73,7 @@ int main()
|
|||||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeOfParticle, (GLvoid *)0);
|
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeOfParticle, (GLvoid *)0);
|
||||||
// color
|
// color
|
||||||
glEnableVertexAttribArray(1);
|
glEnableVertexAttribArray(1);
|
||||||
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeOfParticle, (GLvoid *)24); // 32
|
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeOfParticle, (GLvoid *)24);
|
||||||
glBindVertexArray(0);
|
glBindVertexArray(0);
|
||||||
|
|
||||||
/************* RENDER LOOP *************/
|
/************* RENDER LOOP *************/
|
||||||
|
@ -8,5 +8,6 @@ layout(location = 0) out vec3 colV;
|
|||||||
void main(void)
|
void main(void)
|
||||||
{
|
{
|
||||||
colV = colIn;
|
colV = colIn;
|
||||||
|
gl_PointSize = 1.0f;
|
||||||
gl_Position = vec4(pos, 1);
|
gl_Position = vec4(pos, 1);
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user