Skip to content

Commit

Permalink
support multisample
Browse files Browse the repository at this point in the history
  • Loading branch information
ccsdu2004 committed Jan 2, 2022
1 parent dd187c9 commit 1f3f21f
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 15 deletions.
3 changes: 1 addition & 2 deletions demo/main-model.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@ uint32_t updateUniformBufferData(char *&data, uint32_t size)
glm::mat4 model = glm::rotate(glm::mat4(1.0f), glm::radians(90.0f), glm::vec3(1.0f, 0.0f, 0.0f));
model *= glm::rotate(glm::mat4(1.0f), time * glm::radians(30.0f), glm::vec3(0.0f, 1.0f, 0.0f));
auto view = glm::lookAt(glm::vec3(0.0f, 4.0f, 0.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, 1.0f));
auto proj = glm::perspective(glm::radians(45.0f),
context->getSwapChainExtent().width / (float)context->getSwapChainExtent().height, 0.1f, 10.0f);
auto proj = glm::perspective(glm::radians(45.0f), context->getSwapChainExtent().width / (float)context->getSwapChainExtent().height, 0.1f, 10.0f);
proj[1][1] *= -1;

model = proj * view * model;
Expand Down
85 changes: 76 additions & 9 deletions source/VK_ContextImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ bool VK_ContextImpl::initVulkanContext(VK_ShaderSet *shaderSet)

createDescriptorSetLayout();

createColorResources();
createDepthResources();
createFramebuffers();
createDescriptorPool();
Expand Down Expand Up @@ -285,6 +286,9 @@ void VK_ContextImpl::cleanupSwapChain()
vkDepthImageView->release();
vkDepthImage->release();

vkColorImageView->release();
vkColorImage->release();

for (auto framebuffer : swapChainFramebuffers) {
vkDestroyFramebuffer(device, framebuffer, getAllocation());
}
Expand Down Expand Up @@ -375,6 +379,7 @@ void VK_ContextImpl::recreateSwapChain()
createRenderPass();
createGraphicsPipeline();

createColorResources();
createDepthResources();
createFramebuffers();

Expand Down Expand Up @@ -450,7 +455,9 @@ bool VK_ContextImpl::pickPhysicalDevice()
for (const auto &device : devices) {
if (isDeviceSuitable(device)) {
physicalDevice = device;
msaaSamples = getMaxUsableSampleCount();
deviceList.push_back(device);
break;
}
}

Expand Down Expand Up @@ -592,24 +599,34 @@ void VK_ContextImpl::createRenderPass()
{
VkAttachmentDescription colorAttachment{};
colorAttachment.format = swapChainImageFormat;
colorAttachment.samples = VK_SAMPLE_COUNT_1_BIT;
colorAttachment.samples = msaaSamples;
colorAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
colorAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
colorAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
colorAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
colorAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
colorAttachment.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
colorAttachment.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;

VkAttachmentDescription depthAttachment{};
depthAttachment.format = findDepthFormat();
depthAttachment.samples = VK_SAMPLE_COUNT_1_BIT;
depthAttachment.samples = msaaSamples;
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{};
colorAttachmentResolve.format = swapChainImageFormat;
colorAttachmentResolve.samples = VK_SAMPLE_COUNT_1_BIT;
colorAttachmentResolve.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
colorAttachmentResolve.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
colorAttachmentResolve.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
colorAttachmentResolve.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
colorAttachmentResolve.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
colorAttachmentResolve.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;

VkAttachmentReference colorAttachmentRef{};
colorAttachmentRef.attachment = 0;
colorAttachmentRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
Expand All @@ -618,11 +635,16 @@ void VK_ContextImpl::createRenderPass()
depthAttachmentRef.attachment = 1;
depthAttachmentRef.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;

VkAttachmentReference colorAttachmentResolveRef{};
colorAttachmentResolveRef.attachment = 2;
colorAttachmentResolveRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;

VkSubpassDescription subpass{};
subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
subpass.colorAttachmentCount = 1;
subpass.pColorAttachments = &colorAttachmentRef;
subpass.pDepthStencilAttachment = &depthAttachmentRef;
subpass.pResolveAttachments = &colorAttachmentResolveRef;

VkSubpassDependency dependency{};
dependency.srcSubpass = VK_SUBPASS_EXTERNAL;
Expand All @@ -635,7 +657,7 @@ void VK_ContextImpl::createRenderPass()
dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;

std::array<VkAttachmentDescription, 2> attachments = {colorAttachment, depthAttachment};
std::array<VkAttachmentDescription, 3> attachments = {colorAttachment, depthAttachment, colorAttachmentResolve };
VkRenderPassCreateInfo renderPassInfo{};
renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
renderPassInfo.attachmentCount = static_cast<uint32_t>(attachments.size());
Expand Down Expand Up @@ -972,7 +994,7 @@ bool VK_ContextImpl::createGraphicsPipeline()
VkPipelineMultisampleStateCreateInfo multisampling{};
multisampling.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
multisampling.sampleShadingEnable = VK_FALSE;
multisampling.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
multisampling.rasterizationSamples = msaaSamples;

VkPipelineColorBlendStateCreateInfo colorBlending{};
colorBlending.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
Expand Down Expand Up @@ -1038,9 +1060,10 @@ void VK_ContextImpl::createFramebuffers()
swapChainFramebuffers.resize(swapChainImageViews.size());

for (size_t i = 0; i < swapChainImageViews.size(); i++) {
std::array<VkImageView, 2> attachments = {
swapChainImageViews[i]->getImageView(),
vkDepthImageView->getImageView()
std::array<VkImageView, 3> attachments = {
vkColorImageView->getImageView(),
vkDepthImageView->getImageView(),
swapChainImageViews[i]->getImageView()
};

VkFramebufferCreateInfo framebufferInfo{};
Expand Down Expand Up @@ -1076,12 +1099,28 @@ bool VK_ContextImpl::createCommandPool()
return true;
}

void VK_ContextImpl::createColorResources()
{
vkColorImage = new VK_ImageImpl(device, this);
VkFormat colorFormat = swapChainImageFormat;
bool ok = vkColorImage->createImage(vkSwapChainExtent.width, vkSwapChainExtent.height, msaaSamples, colorFormat,
VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
if (!ok)
std::cerr << "create color image failed\n";

auto createInfo = VK_ImageView::createImageViewCreateInfo(vkColorImage->getImage(), colorFormat);
createInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
vkColorImageView = new VK_ImageViewImpl(device, this);
vkColorImageView->create(createInfo, 1);
}

void VK_ContextImpl::createDepthResources()
{
VkFormat depthFormat = findDepthFormat();

vkDepthImage = new VK_ImageImpl(device, this);
bool ok = vkDepthImage->createImage(vkSwapChainExtent.width, vkSwapChainExtent.height, depthFormat,
bool ok = vkDepthImage->createImage(vkSwapChainExtent.width, vkSwapChainExtent.height, msaaSamples, depthFormat,
VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
if (!ok)
Expand Down Expand Up @@ -1690,6 +1729,34 @@ void VK_ContextImpl::endSingleTimeCommands(VkCommandBuffer commandBuffer)
vkFreeCommandBuffers(device, commandPool, 1, &commandBuffer);
}

VkSampleCountFlagBits VK_ContextImpl::getMaxUsableSampleCount()
{
VkPhysicalDeviceProperties physicalDeviceProperties;
vkGetPhysicalDeviceProperties(physicalDevice, &physicalDeviceProperties);

VkSampleCountFlags counts = physicalDeviceProperties.limits.framebufferColorSampleCounts & physicalDeviceProperties.limits.framebufferDepthSampleCounts;
if (counts & VK_SAMPLE_COUNT_64_BIT) {
return VK_SAMPLE_COUNT_64_BIT;
}
if (counts & VK_SAMPLE_COUNT_32_BIT) {
return VK_SAMPLE_COUNT_32_BIT;
}
if (counts & VK_SAMPLE_COUNT_16_BIT) {
return VK_SAMPLE_COUNT_16_BIT;
}
if (counts & VK_SAMPLE_COUNT_8_BIT) {
return VK_SAMPLE_COUNT_8_BIT;
}
if (counts & VK_SAMPLE_COUNT_4_BIT) {
return VK_SAMPLE_COUNT_4_BIT;
}
if (counts & VK_SAMPLE_COUNT_2_BIT) {
return VK_SAMPLE_COUNT_2_BIT;
}

return VK_SAMPLE_COUNT_1_BIT;
}

void VK_ContextImpl::generateMipmaps(VkImage image, VkFormat imageFormat, int32_t texWidth,
int32_t texHeight,
uint32_t mipLevels)
Expand Down
6 changes: 3 additions & 3 deletions source/VK_ImageImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ bool VK_ImageImpl::load(const std::string &filename)

mipLevels = static_cast<uint32_t>(std::floor(std::log2(std::max(width, height)))) + 1;

createImage(width, height, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
createImage(width, height, VK_SAMPLE_COUNT_1_BIT, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);

context->transitionImageLayout(textureImage, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, mipLevels);
context->copyBufferToImage(stagingBuffer, textureImage, static_cast<uint32_t>(width), static_cast<uint32_t>(height));
Expand Down Expand Up @@ -84,7 +84,7 @@ void VK_ImageImpl::release()
delete this;
}

bool VK_ImageImpl::createImage(uint32_t width, uint32_t height, VkFormat format, VkImageTiling tiling, VkImageUsageFlags usage, VkMemoryPropertyFlags properties)
bool VK_ImageImpl::createImage(uint32_t width, uint32_t height, VkSampleCountFlagBits sample, VkFormat format, VkImageTiling tiling, VkImageUsageFlags usage, VkMemoryPropertyFlags properties)
{
createInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
createInfo.imageType = VK_IMAGE_TYPE_2D;
Expand All @@ -97,7 +97,7 @@ bool VK_ImageImpl::createImage(uint32_t width, uint32_t height, VkFormat format,
createInfo.tiling = tiling;
createInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
createInfo.usage = usage;
createInfo.samples = VK_SAMPLE_COUNT_1_BIT;
createInfo.samples = sample;
createInfo.queueFamilyIndexCount = 0;
createInfo.pQueueFamilyIndices = nullptr;
createInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
Expand Down
2 changes: 1 addition & 1 deletion source/VK_ImageImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class VK_ImageImpl : public VK_Image
~VK_ImageImpl();
public:
bool load(const std::string& filename);
bool createImage(uint32_t width, uint32_t height, VkFormat format, VkImageTiling tiling, VkImageUsageFlags usage, VkMemoryPropertyFlags properties);
bool createImage(uint32_t width, uint32_t height, VkSampleCountFlagBits sample, VkFormat format, VkImageTiling tiling, VkImageUsageFlags usage, VkMemoryPropertyFlags properties);

VkImage getImage()const override;
int getWidth()const override;
Expand Down

0 comments on commit 1f3f21f

Please sign in to comment.