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.
This commit is contained in:
Ricardo Garcia 2021-01-31 10:54:03 +01:00
parent 9661ce0ba0
commit 8599cab275
2 changed files with 18 additions and 11 deletions

View file

@ -63,7 +63,7 @@ qvkrenderpass_t vk_renderpasses[RP_COUNT] = {
// RP_WORLD // RP_WORLD
{ {
.rp = VK_NULL_HANDLE, .rp = VK_NULL_HANDLE,
.colorLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR, .colorLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD,
.sampleCount = VK_SAMPLE_COUNT_1_BIT .sampleCount = VK_SAMPLE_COUNT_1_BIT
}, },
// RP_UI // RP_UI
@ -444,16 +444,16 @@ static VkResult CreateRenderpasses()
/* /*
* world view setup * 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[] = { VkAttachmentDescription worldAttachments[] = {
// color attachment // Single-sample color attachment.
{ {
.flags = 0, .flags = 0,
.format = vk_swapchain.format, .format = vk_swapchain.format,
.samples = VK_SAMPLE_COUNT_1_BIT, .samples = VK_SAMPLE_COUNT_1_BIT,
// The color attachment is loaded from the previous frame and stored .loadOp = (msaaEnabled ? VK_ATTACHMENT_LOAD_OP_DONT_CARE : VK_ATTACHMENT_LOAD_OP_LOAD),
// 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,
.storeOp = VK_ATTACHMENT_STORE_OP_STORE, .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE, .stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE,
.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE, .stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE,
@ -472,16 +472,16 @@ static VkResult CreateRenderpasses()
.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED, .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL .finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
}, },
// MSAA resolve attachment // MSAA attachment
{ {
.flags = 0, .flags = 0,
.format = vk_swapchain.format, .format = vk_swapchain.format,
.samples = vk_renderpasses[RP_WORLD].sampleCount, .samples = vk_renderpasses[RP_WORLD].sampleCount,
.loadOp = msaaEnabled ? vk_renderpasses[RP_WORLD].colorLoadOp : VK_ATTACHMENT_LOAD_OP_DONT_CARE, .loadOp = (msaaEnabled ? VK_ATTACHMENT_LOAD_OP_LOAD : VK_ATTACHMENT_LOAD_OP_DONT_CARE),
.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE, .storeOp = (msaaEnabled ? VK_ATTACHMENT_STORE_OP_STORE : VK_ATTACHMENT_STORE_OP_DONT_CARE),
.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE, .stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE,
.stencilStoreOp = VK_ATTACHMENT_STORE_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 .finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
} }
}; };

View file

@ -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_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)); 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) void QVk_CreateTexture(qvktexture_t *texture, const unsigned char *data, uint32_t width, uint32_t height, qvksampler_t samplerType, qboolean clampToEdge)