diff options
| -rw-r--r-- | src/entities.cpp | 5 | ||||
| -rw-r--r-- | src/window.cpp | 234 | ||||
| -rw-r--r-- | src/window.hpp | 5 |
3 files changed, 191 insertions, 53 deletions
diff --git a/src/entities.cpp b/src/entities.cpp index 8d9206b..70b3a58 100644 --- a/src/entities.cpp +++ b/src/entities.cpp @@ -257,12 +257,11 @@ void EntityType_Init() { VkPipelineRasterizationStateCreateInfo vkPipelineRasterizationStateCreateInfoLine{vkPipelineRasterizationStateCreateInfoFill}; vkPipelineRasterizationStateCreateInfoLine.polygonMode = VK_POLYGON_MODE_LINE; - // TODO MultiSampling VkPipelineMultisampleStateCreateInfo vkPipelineMultisampleStateCreateInfo; vkPipelineMultisampleStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; vkPipelineMultisampleStateCreateInfo.pNext = nullptr; vkPipelineMultisampleStateCreateInfo.flags = 0; - vkPipelineMultisampleStateCreateInfo.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; + vkPipelineMultisampleStateCreateInfo.rasterizationSamples = renderSampleCount; vkPipelineMultisampleStateCreateInfo.sampleShadingEnable = VK_FALSE; vkPipelineMultisampleStateCreateInfo.minSampleShading = 0.0f; vkPipelineMultisampleStateCreateInfo.pSampleMask = nullptr; @@ -363,7 +362,7 @@ void EntityType_Init() { vkGraphicsPipelineCreateInfo[i].pColorBlendState = &vkPipelineColorBlendStateCreateInfo; vkGraphicsPipelineCreateInfo[i].pDynamicState = &vkPipelineDynamicStateCreateInfo; vkGraphicsPipelineCreateInfo[i].layout = vkPipelineLayout_Texture; - vkGraphicsPipelineCreateInfo[i].renderPass = vkRenderPass; + vkGraphicsPipelineCreateInfo[i].renderPass = renderRenderPass; vkGraphicsPipelineCreateInfo[i].subpass = 0; vkGraphicsPipelineCreateInfo[i].basePipelineHandle = VK_NULL_HANDLE; vkGraphicsPipelineCreateInfo[i].basePipelineIndex = {}; diff --git a/src/window.cpp b/src/window.cpp index 5d71e98..de1a6ea 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -38,6 +38,7 @@ unsigned int selectedPresentIndex = -1u; unsigned int swapchainLength = 0u; VkSwapchainKHR vkSwapchainKHR = VK_NULL_HANDLE; VkSurfaceFormatKHR vkSurfaceFormatKHR; +VkFormat depthFormat; VkPresentModeKHR vkPresentModeKHR; VkExtent2D extent; VkImage *swapchainImages = nullptr; @@ -45,9 +46,16 @@ VkImageView *swapchainImageViews = nullptr; VkImage *renderImages = nullptr; VkImageView *renderImageViews = nullptr; VkDeviceMemory renderImagesMemory; -VkBuffer renderImagesBuffer; +VkImage *colorImages = nullptr; +VkImageView *colorImageViews = nullptr; +VkDeviceMemory colorImagesMemory; +VkImage *depthImages = nullptr; +VkImageView *depthImageViews = nullptr; +VkDeviceMemory depthImagesMemory; VkSampler presentSampler; +VkSampleCountFlagBits renderSampleCount; VkRenderPass presentRenderPass; +VkRenderPass renderRenderPass; VkDescriptorSetLayout vkDescriptorSetLayout; VkDescriptorPool presentDescriptorPool; VkDescriptorSet presentDescriptorSets[MAX_FRAMES_IN_FLIGHT]; @@ -115,6 +123,20 @@ unsigned int FindMemoryTypeIndex(uint32_t typeFilter, VkMemoryPropertyFlags memP return 0; } +VkFormat FindSupportedFormat(long candidateCount, const VkFormat *candidates, VkImageTiling tiling, VkFormatFeatureFlags flags) { + for (long i = 0; i < candidateCount; ++i) { + VkFormatProperties props; + vkGetPhysicalDeviceFormatProperties(vkPhysicalDevice, candidates[i], &props); + if (tiling == VK_IMAGE_TILING_LINEAR && (props.linearTilingFeatures & flags) == flags) { + return candidates[i]; + } else if (tiling == VK_IMAGE_TILING_OPTIMAL && (props.optimalTilingFeatures & flags) == flags) { + return candidates[i]; + } + } + fprintf(stdout, "[vulkan] Failed to find appropriate format: tiling: %u - flags: %u\n", tiling, flags); + return VkFormat(0); +} + void BeginTransferBuffer(VkDeviceSize requestedMemorySize, VkBuffer &buffer, VkDeviceMemory &deviceMemory, void *&deviceData) { VkBufferCreateInfo transferBufferCI; transferBufferCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; @@ -432,6 +454,35 @@ void InitVulkan() { vkGetDeviceQueue(vkDevice, transferFamilyIndex, 0, &transferQueue); } + // surface formats + { + VkFormat acceptableDepthFormats[3] = { + VK_FORMAT_D32_SFLOAT, + VK_FORMAT_D32_SFLOAT_S8_UINT, + VK_FORMAT_D24_UNORM_S8_UINT, + }; + depthFormat = FindSupportedFormat(3, acceptableDepthFormats, VK_IMAGE_TILING_OPTIMAL, VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT); + } + + // sampler + { + VkSampleCountFlags counts = vkPhysicalDeviceProperties.limits.framebufferColorSampleCounts & vkPhysicalDeviceProperties.limits.framebufferDepthSampleCounts; + + if (counts & VK_SAMPLE_COUNT_64_BIT) { + renderSampleCount = VK_SAMPLE_COUNT_64_BIT; + } else if (counts & VK_SAMPLE_COUNT_32_BIT) { + renderSampleCount = VK_SAMPLE_COUNT_32_BIT; + } else if (counts & VK_SAMPLE_COUNT_16_BIT) { + renderSampleCount = VK_SAMPLE_COUNT_16_BIT; + } else if (counts & VK_SAMPLE_COUNT_8_BIT) { + renderSampleCount = VK_SAMPLE_COUNT_8_BIT; + } else if (counts & VK_SAMPLE_COUNT_4_BIT) { + renderSampleCount = VK_SAMPLE_COUNT_4_BIT; + } else if (counts & VK_SAMPLE_COUNT_2_BIT) { + renderSampleCount = VK_SAMPLE_COUNT_2_BIT; + } + } + // generic present sampler VkSamplerCreateInfo samplerCreateInfo; samplerCreateInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; @@ -456,6 +507,36 @@ void InitVulkan() { vkCreateSampler(vkDevice, &samplerCreateInfo, vkAllocator, &presentSampler); } +void CreateImageResources_Inner(VkImageCreateInfo *imageCreateInfo, VkImageViewCreateInfo *imageViewCreateInfo, VkBufferUsageFlagBits bufferUsageFlagBits, VkBuffer *imagesBuffer, VkImage *images, VkImageView *imageViews, VkDeviceMemory *deviceMemory) { + VkImage tmpImage; + vkCreateImage(vkDevice, imageCreateInfo, vkAllocator, &tmpImage); + + VkMemoryRequirements imageMemoryRequirements; + vkGetImageMemoryRequirements(vkDevice, tmpImage, &imageMemoryRequirements); + + VkDeviceSize paddedImageSize = imageMemoryRequirements.size + (imageMemoryRequirements.alignment - (imageMemoryRequirements.size % imageMemoryRequirements.alignment)); + assert(paddedImageSize % imageMemoryRequirements.alignment == 0); + + vkDestroyImage(vkDevice, tmpImage, vkAllocator); + + VkMemoryAllocateInfo vkMemoryAllocateInfo{}; + vkMemoryAllocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; + vkMemoryAllocateInfo.pNext = nullptr; + vkMemoryAllocateInfo.allocationSize = paddedImageSize * MAX_FRAMES_IN_FLIGHT; + vkMemoryAllocateInfo.memoryTypeIndex = FindMemoryTypeIndex(imageMemoryRequirements.memoryTypeBits, + VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + + vkAllocateMemory(vkDevice, &vkMemoryAllocateInfo, vkAllocator, deviceMemory); + + for (long i = 0; i < MAX_FRAMES_IN_FLIGHT; ++i) { + vkCreateImage(vkDevice, imageCreateInfo, vkAllocator, &images[i]); + vkBindImageMemory(vkDevice, images[i], *deviceMemory, paddedImageSize * i); + + imageViewCreateInfo->image = images[i]; + vkCreateImageView(vkDevice, imageViewCreateInfo, vkAllocator, &imageViews[i]); + } +} + void CreateSwapchain() { VkSurfaceCapabilitiesKHR surfaceCapabilities; @@ -594,56 +675,33 @@ void CreateSwapchain() { renderTargetImageCI.pQueueFamilyIndices = nullptr; renderTargetImageCI.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; - VkImage tmpImage; - vkCreateImage(vkDevice, &renderTargetImageCI, vkAllocator, &tmpImage); - - VkMemoryRequirements imageMemoryRequirements; - vkGetImageMemoryRequirements(vkDevice, tmpImage, &imageMemoryRequirements); - - VkDeviceSize paddedImageSize = imageMemoryRequirements.size + (imageMemoryRequirements.alignment - (imageMemoryRequirements.size % imageMemoryRequirements.alignment)); - assert(paddedImageSize % imageMemoryRequirements.alignment == 0); - - vkDestroyImage(vkDevice, tmpImage, vkAllocator); - - VkBufferCreateInfo imageBufferCI{}; - imageBufferCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; - imageBufferCI.pNext = nullptr; - imageBufferCI.flags = 0; - imageBufferCI.size = paddedImageSize * MAX_FRAMES_IN_FLIGHT; - imageBufferCI.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT; - imageBufferCI.sharingMode = VK_SHARING_MODE_EXCLUSIVE; - imageBufferCI.queueFamilyIndexCount = 0; - imageBufferCI.pQueueFamilyIndices = nullptr; - vkCreateBuffer(vkDevice, &imageBufferCI, vkAllocator, &renderImagesBuffer); - - VkMemoryAllocateInfo vkMemoryAllocateInfo{}; - vkMemoryAllocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; - vkMemoryAllocateInfo.pNext = nullptr; - vkMemoryAllocateInfo.allocationSize = imageBufferCI.size; - vkMemoryAllocateInfo.memoryTypeIndex = FindMemoryTypeIndex(imageMemoryRequirements.memoryTypeBits, - VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); - - vkAllocateMemory(vkDevice, &vkMemoryAllocateInfo, vkAllocator, &renderImagesMemory); - - vkBindBufferMemory(vkDevice, renderImagesBuffer, renderImagesMemory, 0); - + // render images renderImages = Pke_New<VkImage>(MAX_FRAMES_IN_FLIGHT); renderImageViews = Pke_New<VkImageView>(MAX_FRAMES_IN_FLIGHT); - - for (long i = 0; i < MAX_FRAMES_IN_FLIGHT; ++i) { - vkCreateImage(vkDevice, &renderTargetImageCI, vkAllocator, &renderImages[i]); - vkBindImageMemory(vkDevice, renderImages[i], renderImagesMemory, paddedImageSize * i); - - vkImageViewCreateInfo.image = renderImages[i]; - vkCreateImageView(vkDevice, &vkImageViewCreateInfo, vkAllocator, &renderImageViews[i]); - } + CreateImageResources_Inner(&renderTargetImageCI, &vkImageViewCreateInfo, VkBufferUsageFlagBits(0), nullptr, renderImages, renderImageViews, &renderImagesMemory); + + // color images + colorImages = Pke_New<VkImage>(MAX_FRAMES_IN_FLIGHT); + colorImageViews = Pke_New<VkImageView>(MAX_FRAMES_IN_FLIGHT); + renderTargetImageCI.samples = renderSampleCount; + renderTargetImageCI.usage = VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; + CreateImageResources_Inner(&renderTargetImageCI, &vkImageViewCreateInfo, VkBufferUsageFlagBits(0), nullptr, colorImages, colorImageViews, &colorImagesMemory); + + // depth images + depthImages = Pke_New<VkImage>(MAX_FRAMES_IN_FLIGHT); + depthImageViews = Pke_New<VkImageView>(MAX_FRAMES_IN_FLIGHT); + renderTargetImageCI.format = depthFormat; + vkImageViewCreateInfo.format = depthFormat; + renderTargetImageCI.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; + vkImageViewCreateInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; + CreateImageResources_Inner(&renderTargetImageCI, &vkImageViewCreateInfo, VkBufferUsageFlagBits(0), nullptr, depthImages, depthImageViews, &depthImagesMemory); } void CreateRenderPass() { VkAttachmentDescription colorAttachment; colorAttachment.flags = {}; colorAttachment.format = vkSurfaceFormatKHR.format; - colorAttachment.samples = VkSampleCountFlagBits::VK_SAMPLE_COUNT_1_BIT; + colorAttachment.samples = VK_SAMPLE_COUNT_1_BIT; colorAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; colorAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; colorAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; @@ -658,12 +716,13 @@ void CreateRenderPass() { VkSubpassDescription subpass; subpass.flags = {}; subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; - subpass.inputAttachmentCount = {}; + subpass.inputAttachmentCount = 0; + subpass.pInputAttachments = nullptr; subpass.colorAttachmentCount = 1; subpass.pColorAttachments = &colorAttachmentRef; subpass.pResolveAttachments = nullptr; subpass.pDepthStencilAttachment = nullptr; - subpass.preserveAttachmentCount = {}; + subpass.preserveAttachmentCount = 0; subpass.pPreserveAttachments = nullptr; VkSubpassDependency subpassDependencies[2]; @@ -697,6 +756,61 @@ void CreateRenderPass() { renderPassInfo.pDependencies = subpassDependencies; if (vkCreateRenderPass(vkDevice, &renderPassInfo, vkAllocator, &presentRenderPass) != VK_SUCCESS) { + throw "failed to create present render pass!"; + } + + colorAttachment.samples = renderSampleCount; + colorAttachment.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + + VkAttachmentDescription depthAttachment; + depthAttachment.flags = 0; + depthAttachment.format = depthFormat; + depthAttachment.samples = renderSampleCount; + depthAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; + depthAttachment.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; + depthAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; + depthAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; + depthAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; + depthAttachment.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; + + VkAttachmentDescription colorAttachmentResolve{colorAttachment}; + colorAttachmentResolve.samples = VK_SAMPLE_COUNT_1_BIT; + colorAttachmentResolve.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; + colorAttachmentResolve.storeOp = VK_ATTACHMENT_STORE_OP_STORE; + colorAttachmentResolve.finalLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + + VkAttachmentReference depthAttachmentRef; + depthAttachmentRef.attachment = 1; + depthAttachmentRef.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; + + VkAttachmentReference colorAttachmentReseolveRef; + colorAttachmentReseolveRef.attachment = 2; + colorAttachmentReseolveRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + + subpass.pColorAttachments = &colorAttachmentRef; + subpass.pResolveAttachments = &colorAttachmentReseolveRef; + subpass.pDepthStencilAttachment = &depthAttachmentRef; + + subpassDependencies[0].srcStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; + subpassDependencies[0].dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; + subpassDependencies[0].srcAccessMask = VK_ACCESS_SHADER_READ_BIT; + subpassDependencies[0].dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + + subpassDependencies[1].srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; + subpassDependencies[1].dstStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; + subpassDependencies[1].srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + subpassDependencies[1].dstAccessMask = VK_ACCESS_SHADER_READ_BIT; + + VkAttachmentDescription attachments[3] = { + colorAttachment, depthAttachment, colorAttachmentResolve + }; + + renderPassInfo.attachmentCount = 3; + renderPassInfo.pAttachments = attachments; + renderPassInfo.dependencyCount = 2; + renderPassInfo.pDependencies = subpassDependencies; + + if (vkCreateRenderPass(vkDevice, &renderPassInfo, vkAllocator, &renderRenderPass) != VK_SUCCESS) { throw "failed to create render pass!"; } } @@ -969,10 +1083,20 @@ void CreateFramebuffers() { if (result != VK_SUCCESS) { throw "failed to create framebuffer"; } - attachments[0] = renderImageViews[i]; - result = vkCreateFramebuffer(vkDevice, &framebufferInfo, vkAllocator, &renderImageFramebuffers[i]); + } + + framebufferInfo.attachmentCount = 3; + framebufferInfo.renderPass = renderRenderPass; + for (long i = 0; i < swapchainLength; ++i) { + VkImageView attachments[] = { + colorImageViews[i], + depthImageViews[i], + renderImageViews[i], + }; + framebufferInfo.pAttachments = attachments; + auto result = vkCreateFramebuffer(vkDevice, &framebufferInfo, vkAllocator, &renderImageFramebuffers[i]); if (result != VK_SUCCESS) { - throw "failed to create render framebuffer"; + throw "failed to create framebuffer"; } } } @@ -1268,12 +1392,23 @@ void DestroySwapchain() { } if (renderImageViews!= nullptr && renderImageViews != CAFE_BABE(VkImageView)) { for (long i = 0; i < swapchainLength; ++i) { + vkDestroyImageView(vkDevice, depthImageViews[i], vkAllocator); + vkDestroyImage(vkDevice, depthImages[i], vkAllocator); + + vkDestroyImageView(vkDevice, colorImageViews[i], vkAllocator); + vkDestroyImage(vkDevice, colorImages[i], vkAllocator); + vkDestroyImageView(vkDevice, renderImageViews[i], vkAllocator); vkDestroyImage(vkDevice, renderImages[i], vkAllocator); } + Pke_Delete<VkImageView>(depthImageViews, swapchainLength); + Pke_Delete<VkImage>(depthImages, swapchainLength); + Pke_Delete<VkImageView>(colorImageViews, swapchainLength); + Pke_Delete<VkImage>(colorImages, swapchainLength); Pke_Delete<VkImageView>(renderImageViews, swapchainLength); Pke_Delete<VkImage>(renderImages, swapchainLength); - vkDestroyBuffer(vkDevice, renderImagesBuffer, vkAllocator); + vkFreeMemory(vkDevice, depthImagesMemory, vkAllocator); + vkFreeMemory(vkDevice, colorImagesMemory, vkAllocator); vkFreeMemory(vkDevice, renderImagesMemory, vkAllocator); } if (swapchainImageViews!= nullptr && swapchainImageViews != CAFE_BABE(VkImageView)) { @@ -1354,6 +1489,7 @@ void DestroyWindow() { vkDestroyDescriptorPool(vkDevice, presentDescriptorPool, vkAllocator); vkDestroyDescriptorPool(vkDevice, imGuiDescriptorPool, vkAllocator); vkDestroyDescriptorSetLayout(vkDevice, vkDescriptorSetLayout, vkAllocator); + vkDestroyRenderPass(vkDevice, renderRenderPass, vkAllocator); vkDestroyRenderPass(vkDevice, presentRenderPass, vkAllocator); vkDestroySurfaceKHR(vkInstance, vkSurfaceKHR, vkAllocator); vkDestroySampler(vkDevice, presentSampler, vkAllocator); diff --git a/src/window.hpp b/src/window.hpp index 84e3d33..a307671 100644 --- a/src/window.hpp +++ b/src/window.hpp @@ -25,6 +25,7 @@ extern VkInstance vkInstance; extern VkPhysicalDevice vkPhysicalDevice; extern VkPhysicalDeviceProperties vkPhysicalDeviceProperties; extern VkSurfaceKHR vkSurfaceKHR; +extern VkFormat depthFormat; extern VkDevice vkDevice; extern VkAllocationCallbacks *vkAllocator; extern VkQueue graphicsQueue; @@ -36,7 +37,9 @@ extern VkCommandBuffer transferCommandBuffer; extern unsigned int graphicsFamilyIndex; extern unsigned int presentFamilyIndex; extern unsigned int transferFamilyIndex; -extern VkRenderPass vkRenderPass; +extern VkRenderPass presentRenderPass; +extern VkRenderPass renderRenderPass; +extern VkSampleCountFlagBits renderSampleCount; struct PKEWindowProperties { unsigned int width = 1280; |
