Performing MSAA on PowerVR using Vulkan

How to optimally perform MSAA in Vulkan on PowerVR hardware

To perform MSAA optimally using Vulkan on PowerVR hardware, the application should use a lazily-allocated MSAA frame buffer attachment, which will be used to render the scene to. The store operation flag should be set to VK_ATTACHMENT_STORE_OP_DONT_CARE as this tells the driver to discard the contents of this buffer after use to save memory bandwidth - the buffer is not to be preserved. There must also be a second frame buffer attachment, which will be used to resolve multi-sampled image. This attachment should have the store operation flag set to VK_ATTACHMENT_STORE_OP_STORE.

This method ensures that the multi-sampled buffer is only allocated by the driver on-chip when required, and the MSAA resolve is performed on-chip and only then written out to system memory.

// Multi-sampled frame buffer attachment that is rendered to.
attachments[0].format = swapChain.colorFormat;
attachments[0].samples = VK_SAMPLE_COUNT_2_BIT; // 2x MSAA
attachments[0].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
                
// No longer required after resolve, this will save memory bandwidth
attachments[0].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
attachments[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
attachments[0].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
attachments[0].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
attachments[0].finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
                
// The frame buffer attachment where the multi-sampled image will be resolved to.
attachments[1].format = swapChain.colorFormat;
attachments[1].samples = VK_SAMPLE_COUNT_1_BIT;
attachments[1].loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
attachments[1].storeOp = VK_ATTACHMENT_STORE_OP_STORE; // Store the resolved image
attachments[1].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
attachments[1].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
attachments[1].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
attachments[1].finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;