Implement multisample support for the triangle benchmark
For now, this has to be enabled manually using
TriangleBenchmark::multisample
Bug: b/158231104
Change-Id: I929da4bf72e6f354aeb089e19fdd6a749f839d3f
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/45689
Presubmit-Ready: Nicolas Capens <nicolascapens@google.com>
Tested-by: Nicolas Capens <nicolascapens@google.com>
Kokoro-Result: kokoro <noreply+kokoro@google.com>
Reviewed-by: Antonio Maiorano <amaiorano@google.com>
diff --git a/tests/VulkanBenchmarks/VulkanBenchmarks.cpp b/tests/VulkanBenchmarks/VulkanBenchmarks.cpp
index 41d51a1..0479341 100644
--- a/tests/VulkanBenchmarks/VulkanBenchmarks.cpp
+++ b/tests/VulkanBenchmarks/VulkanBenchmarks.cpp
@@ -401,7 +401,7 @@
vk::SwapchainKHR swapchain;
- std::vector<vk::Image> images;
+ std::vector<vk::Image> images; // Weak pointers. Presentable images owned by swapchain object.
std::vector<vk::ImageView> imageViews;
};
@@ -453,7 +453,7 @@
swapchain = new Swapchain(physicalDevice, device, window);
renderPass = createRenderPass(swapchain->colorFormat);
- framebuffers = createFramebuffers(renderPass);
+ createFramebuffers(renderPass);
prepareVertices();
@@ -482,7 +482,11 @@
for(auto &framebuffer : framebuffers)
{
- device.destroyFramebuffer(framebuffer);
+ device.destroyFramebuffer(framebuffer.framebuffer);
+
+ device.destroyImage(framebuffer.multisampleImage.image);
+ device.destroyImageView(framebuffer.multisampleImage.imageView);
+ device.freeMemory(framebuffer.multisampleImage.imageMemory);
}
device.destroyRenderPass(renderPass);
@@ -535,7 +539,7 @@
clearValues[0].color = vk::ClearColorValue(std::array<float, 4>{ 0.5f, 0.5f, 0.5f, 1.0f });
vk::RenderPassBeginInfo renderPassBeginInfo;
- renderPassBeginInfo.framebuffer = framebuffers[i];
+ renderPassBeginInfo.framebuffer = framebuffers[i].framebuffer;
renderPassBeginInfo.renderPass = renderPass;
renderPassBeginInfo.renderArea.offset.x = 0;
renderPassBeginInfo.renderArea.offset.y = 0;
@@ -627,14 +631,60 @@
vertices.inputState.pVertexAttributeDescriptions = vertices.inputAttributes.data();
}
- std::vector<vk::Framebuffer> createFramebuffers(vk::RenderPass renderPass)
+ void createFramebuffers(vk::RenderPass renderPass)
{
- std::vector<vk::Framebuffer> framebuffers(swapchain->imageCount());
+ framebuffers.resize(swapchain->imageCount());
for(size_t i = 0; i < framebuffers.size(); i++)
{
- std::array<vk::ImageView, 1> attachments; // color only
- attachments[0] = swapchain->getImageView(i);
+ std::vector<vk::ImageView> attachments(multisample ? 2 : 1);
+
+ if(multisample)
+ {
+ // Create multisample images
+ vk::ImageCreateInfo imageInfo;
+ imageInfo.imageType = vk::ImageType::e2D;
+ imageInfo.format = swapchain->colorFormat;
+ imageInfo.tiling = vk::ImageTiling::eOptimal;
+ imageInfo.initialLayout = vk::ImageLayout::eGeneral;
+ imageInfo.usage = vk::ImageUsageFlagBits::eColorAttachment;
+ imageInfo.samples = vk::SampleCountFlagBits::e4;
+ imageInfo.extent = { windowSize.width, windowSize.height, 1 };
+ imageInfo.mipLevels = 1;
+ imageInfo.arrayLayers = 1;
+
+ framebuffers[i].multisampleImage.image = device.createImage(imageInfo);
+
+ vk::MemoryRequirements memoryRequirements = device.getImageMemoryRequirements(framebuffers[i].multisampleImage.image);
+
+ vk::MemoryAllocateInfo allocateInfo;
+ allocateInfo.allocationSize = memoryRequirements.size;
+ allocateInfo.memoryTypeIndex = getMemoryTypeIndex(memoryRequirements.memoryTypeBits, vk::MemoryPropertyFlagBits::eDeviceLocal);
+
+ framebuffers[i].multisampleImage.imageMemory = device.allocateMemory(allocateInfo);
+
+ device.bindImageMemory(framebuffers[i].multisampleImage.image, framebuffers[i].multisampleImage.imageMemory, 0);
+
+ vk::ImageViewCreateInfo colorAttachmentView;
+ colorAttachmentView.image = framebuffers[i].multisampleImage.image;
+ colorAttachmentView.viewType = vk::ImageViewType::e2D;
+ colorAttachmentView.format = swapchain->colorFormat;
+ colorAttachmentView.subresourceRange.aspectMask = vk::ImageAspectFlagBits::eColor;
+ colorAttachmentView.subresourceRange.baseMipLevel = 0;
+ colorAttachmentView.subresourceRange.levelCount = 1;
+ colorAttachmentView.subresourceRange.baseArrayLayer = 0;
+ colorAttachmentView.subresourceRange.layerCount = 1;
+
+ framebuffers[i].multisampleImage.imageView = device.createImageView(colorAttachmentView);
+
+ // We'll be rendering to attachment location 0
+ attachments[0] = framebuffers[i].multisampleImage.imageView;
+ attachments[1] = swapchain->getImageView(i); // Resolve attachment
+ }
+ else
+ {
+ attachments[0] = swapchain->getImageView(i);
+ }
vk::FramebufferCreateInfo framebufferCreateInfo;
@@ -645,33 +695,59 @@
framebufferCreateInfo.height = windowSize.height;
framebufferCreateInfo.layers = 1;
- framebuffers[i] = device.createFramebuffer(framebufferCreateInfo);
+ framebuffers[i].framebuffer = device.createFramebuffer(framebufferCreateInfo);
}
-
- return framebuffers;
}
vk::RenderPass createRenderPass(vk::Format colorFormat)
{
- std::array<vk::AttachmentDescription, 1> attachments;
+ std::vector<vk::AttachmentDescription> attachments(multisample ? 2 : 1);
- attachments[0].format = colorFormat;
- attachments[0].samples = vk::SampleCountFlagBits::e1;
- attachments[0].loadOp = vk::AttachmentLoadOp::eClear;
- attachments[0].storeOp = vk::AttachmentStoreOp::eStore;
- attachments[0].stencilLoadOp = vk::AttachmentLoadOp::eDontCare;
- attachments[0].stencilStoreOp = vk::AttachmentStoreOp::eDontCare;
- attachments[0].initialLayout = vk::ImageLayout::eUndefined;
- attachments[0].finalLayout = vk::ImageLayout::ePresentSrcKHR;
+ if(multisample)
+ {
+ attachments[0].format = colorFormat;
+ attachments[0].samples = vk::SampleCountFlagBits::e4;
+ attachments[0].loadOp = vk::AttachmentLoadOp::eClear;
+ attachments[0].storeOp = vk::AttachmentStoreOp::eStore;
+ attachments[0].stencilLoadOp = vk::AttachmentLoadOp::eDontCare;
+ attachments[0].stencilStoreOp = vk::AttachmentStoreOp::eDontCare;
+ attachments[0].initialLayout = vk::ImageLayout::eUndefined;
+ attachments[0].finalLayout = vk::ImageLayout::eColorAttachmentOptimal;
- vk::AttachmentReference colorReference;
- colorReference.attachment = 0;
- colorReference.layout = vk::ImageLayout::eColorAttachmentOptimal;
+ attachments[1].format = colorFormat;
+ attachments[1].samples = vk::SampleCountFlagBits::e1;
+ attachments[1].loadOp = vk::AttachmentLoadOp::eDontCare;
+ attachments[1].storeOp = vk::AttachmentStoreOp::eStore;
+ attachments[1].stencilLoadOp = vk::AttachmentLoadOp::eDontCare;
+ attachments[1].stencilStoreOp = vk::AttachmentStoreOp::eDontCare;
+ attachments[1].initialLayout = vk::ImageLayout::eUndefined;
+ attachments[1].finalLayout = vk::ImageLayout::ePresentSrcKHR;
+ }
+ else
+ {
+ attachments[0].format = colorFormat;
+ attachments[0].samples = vk::SampleCountFlagBits::e1;
+ attachments[0].loadOp = vk::AttachmentLoadOp::eDontCare;
+ attachments[0].storeOp = vk::AttachmentStoreOp::eStore;
+ attachments[0].stencilLoadOp = vk::AttachmentLoadOp::eDontCare;
+ attachments[0].stencilStoreOp = vk::AttachmentStoreOp::eDontCare;
+ attachments[0].initialLayout = vk::ImageLayout::eUndefined;
+ attachments[0].finalLayout = vk::ImageLayout::ePresentSrcKHR;
+ }
+
+ vk::AttachmentReference attachment0;
+ attachment0.attachment = 0;
+ attachment0.layout = vk::ImageLayout::eColorAttachmentOptimal;
+
+ vk::AttachmentReference attachment1;
+ attachment1.attachment = 1;
+ attachment1.layout = vk::ImageLayout::eColorAttachmentOptimal;
vk::SubpassDescription subpassDescription;
subpassDescription.pipelineBindPoint = vk::PipelineBindPoint::eGraphics;
subpassDescription.colorAttachmentCount = 1;
- subpassDescription.pColorAttachments = &colorReference;
+ subpassDescription.pResolveAttachments = multisample ? &attachment1 : nullptr;
+ subpassDescription.pColorAttachments = &attachment0;
std::array<vk::SubpassDependency, 2> dependencies;
@@ -765,7 +841,7 @@
depthStencilState.front = depthStencilState.back;
vk::PipelineMultisampleStateCreateInfo multisampleState;
- multisampleState.rasterizationSamples = vk::SampleCountFlagBits::e1;
+ multisampleState.rasterizationSamples = multisample ? vk::SampleCountFlagBits::e4 : vk::SampleCountFlagBits::e1;
multisampleState.pSampleMask = nullptr;
const char *vertexShader = R"(#version 310 es
@@ -821,12 +897,27 @@
}
const vk::Extent2D windowSize = { 1280, 720 };
+ const bool multisample = false;
Window *window = nullptr;
Swapchain *swapchain = nullptr;
+ struct Image
+ {
+ vk::Image image;
+ vk::DeviceMemory imageMemory;
+ vk::ImageView imageView;
+ };
+
+ struct Framebuffer
+ {
+ vk::Framebuffer framebuffer;
+
+ Image multisampleImage;
+ };
+
vk::RenderPass renderPass;
- std::vector<vk::Framebuffer> framebuffers;
+ std::vector<Framebuffer> framebuffers;
uint32_t currentFrameBuffer = 0;
struct VertexBuffer