From 8599cab2756624b68387cb8b16e29a796e9e9233 Mon Sep 17 00:00:00 2001 From: Ricardo Garcia Date: Sun, 31 Jan 2021 10:54:03 +0100 Subject: [PATCH] Load framebuffer contents correctly for MSAA The contents of the previous drawn frame, used to mask geometry glitches due to geometry sometimes not being watertight, was not being correctly loaded for MSAA cases. When MSAA is not used, the single-sample attachment needs to be loaded and stored. With MSAA enabled, it's the multisample attachment the one needing to be loaded and stored. --- src/client/refresh/vk/vk_common.c | 20 ++++++++++---------- src/client/refresh/vk/vk_image.c | 9 ++++++++- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/src/client/refresh/vk/vk_common.c b/src/client/refresh/vk/vk_common.c index e3fd7af2..1229ca72 100644 --- a/src/client/refresh/vk/vk_common.c +++ b/src/client/refresh/vk/vk_common.c @@ -63,7 +63,7 @@ qvkrenderpass_t vk_renderpasses[RP_COUNT] = { // RP_WORLD { .rp = VK_NULL_HANDLE, - .colorLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR, + .colorLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD, .sampleCount = VK_SAMPLE_COUNT_1_BIT }, // RP_UI @@ -444,16 +444,16 @@ static VkResult CreateRenderpasses() /* * world view setup */ + // The color attachment is loaded from the previous frame and stored + // after the frame is drawn to mask geometry errors in the skybox + // that may leave some pixels without coverage. VkAttachmentDescription worldAttachments[] = { - // color attachment + // Single-sample color attachment. { .flags = 0, .format = vk_swapchain.format, .samples = VK_SAMPLE_COUNT_1_BIT, - // The color attachment is loaded from the previous frame and stored - // after the frame is drawn to mask geometry errors in the skybox - // that may leave some pixels without coverage. - .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD, + .loadOp = (msaaEnabled ? VK_ATTACHMENT_LOAD_OP_DONT_CARE : VK_ATTACHMENT_LOAD_OP_LOAD), .storeOp = VK_ATTACHMENT_STORE_OP_STORE, .stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE, .stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE, @@ -472,16 +472,16 @@ static VkResult CreateRenderpasses() .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED, .finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL }, - // MSAA resolve attachment + // MSAA attachment { .flags = 0, .format = vk_swapchain.format, .samples = vk_renderpasses[RP_WORLD].sampleCount, - .loadOp = msaaEnabled ? vk_renderpasses[RP_WORLD].colorLoadOp : VK_ATTACHMENT_LOAD_OP_DONT_CARE, - .storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE, + .loadOp = (msaaEnabled ? VK_ATTACHMENT_LOAD_OP_LOAD : VK_ATTACHMENT_LOAD_OP_DONT_CARE), + .storeOp = (msaaEnabled ? VK_ATTACHMENT_STORE_OP_STORE : VK_ATTACHMENT_STORE_OP_DONT_CARE), .stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE, .stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE, - .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED, + .initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, .finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL } }; diff --git a/src/client/refresh/vk/vk_image.c b/src/client/refresh/vk/vk_image.c index e0c52e24..fe833690 100644 --- a/src/client/refresh/vk/vk_image.c +++ b/src/client/refresh/vk/vk_image.c @@ -397,7 +397,14 @@ void QVk_CreateColorBuffer(VkSampleCountFlagBits sampleCount, qvktexture_t *colo VK_VERIFY(QVk_CreateImage(vk_swapchain.extent.width, vk_swapchain.extent.height, colorBuffer->format, VK_IMAGE_TILING_OPTIMAL, extraFlags | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, colorBuffer)); VK_VERIFY(QVk_CreateImageView(&colorBuffer->resource.image, VK_IMAGE_ASPECT_COLOR_BIT, &colorBuffer->imageView, colorBuffer->format, colorBuffer->mipLevels)); - ChangeColorBufferLayout(colorBuffer->resource.image, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); + // The single-sample color attachment ends every frame as + // SHADER_READ_ONLY_OPTIMAL as used in the post-processing stage, so its + // initial image layout is specified as such. + // + // The multi-sample color attachment is always COLOR_ATTACHMENT_OPTIMAL. + // + const VkImageLayout newLayout = ((sampleCount == VK_SAMPLE_COUNT_1_BIT) ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); + ChangeColorBufferLayout(colorBuffer->resource.image, VK_IMAGE_LAYOUT_UNDEFINED, newLayout); } void QVk_CreateTexture(qvktexture_t *texture, const unsigned char *data, uint32_t width, uint32_t height, qvksampler_t samplerType, qboolean clampToEdge)