// Copyright 2021 The SwiftShader Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #include "Util.hpp" #include "VulkanTester.hpp" #include "benchmark/benchmark.h" #include <cassert> class ClearImageBenchmark { public: void initialize(vk::Format clearFormat, vk::ImageAspectFlagBits clearAspect) { tester.initialize(); auto &device = tester.getDevice(); auto &physicalDevice = tester.getPhysicalDevice(); vk::ImageCreateInfo imageInfo; imageInfo.imageType = vk::ImageType::e2D; imageInfo.format = clearFormat; imageInfo.tiling = vk::ImageTiling::eOptimal; imageInfo.initialLayout = vk::ImageLayout::eGeneral; imageInfo.usage = vk::ImageUsageFlagBits::eTransferDst; imageInfo.samples = vk::SampleCountFlagBits::e4; imageInfo.extent = vk::Extent3D(1024, 1024, 1); imageInfo.mipLevels = 1; imageInfo.arrayLayers = 1; image = device.createImage(imageInfo); vk::MemoryRequirements memoryRequirements = device.getImageMemoryRequirements(image); vk::MemoryAllocateInfo allocateInfo; allocateInfo.allocationSize = memoryRequirements.size; allocateInfo.memoryTypeIndex = Util::getMemoryTypeIndex(physicalDevice, memoryRequirements.memoryTypeBits); memory = device.allocateMemory(allocateInfo); device.bindImageMemory(image, memory, 0); vk::CommandPoolCreateInfo commandPoolCreateInfo; commandPoolCreateInfo.queueFamilyIndex = tester.getQueueFamilyIndex(); commandPool = device.createCommandPool(commandPoolCreateInfo); vk::CommandBufferAllocateInfo commandBufferAllocateInfo; commandBufferAllocateInfo.commandPool = commandPool; commandBufferAllocateInfo.commandBufferCount = 1; commandBuffer = device.allocateCommandBuffers(commandBufferAllocateInfo)[0]; vk::CommandBufferBeginInfo commandBufferBeginInfo; commandBufferBeginInfo.flags = {}; commandBuffer.begin(commandBufferBeginInfo); vk::ImageSubresourceRange range; range.aspectMask = clearAspect; range.baseMipLevel = 0; range.levelCount = 1; range.baseArrayLayer = 0; range.layerCount = 1; if(clearAspect == vk::ImageAspectFlagBits::eColor) { vk::ClearColorValue clearColorValue; clearColorValue.float32[0] = 0.0f; clearColorValue.float32[1] = 1.0f; clearColorValue.float32[2] = 0.0f; clearColorValue.float32[3] = 1.0f; commandBuffer.clearColorImage(image, vk::ImageLayout::eGeneral, &clearColorValue, 1, &range); } else if(clearAspect == vk::ImageAspectFlagBits::eDepth) { vk::ClearDepthStencilValue clearDepthStencilValue; clearDepthStencilValue.depth = 1.0f; clearDepthStencilValue.stencil = 0xFF; commandBuffer.clearDepthStencilImage(image, vk::ImageLayout::eGeneral, &clearDepthStencilValue, 1, &range); } else assert(false); commandBuffer.end(); } ~ClearImageBenchmark() { auto &device = tester.getDevice(); device.freeCommandBuffers(commandPool, 1, &commandBuffer); device.destroyCommandPool(commandPool, nullptr); device.freeMemory(memory, nullptr); device.destroyImage(image, nullptr); } void clear() { auto &queue = tester.getQueue(); vk::SubmitInfo submitInfo; submitInfo.commandBufferCount = 1; submitInfo.pCommandBuffers = &commandBuffer; queue.submit(1, &submitInfo, nullptr); queue.waitIdle(); } private: VulkanTester tester; vk::Image image; // Owning handle vk::DeviceMemory memory; // Owning handle vk::CommandPool commandPool; // Owning handle vk::CommandBuffer commandBuffer; // Owning handle }; static void ClearImage(benchmark::State &state, vk::Format clearFormat, vk::ImageAspectFlagBits clearAspect) { ClearImageBenchmark benchmark; benchmark.initialize(clearFormat, clearAspect); // Execute once to have the Reactor routine generated. benchmark.clear(); for(auto _ : state) { benchmark.clear(); } } BENCHMARK_CAPTURE(ClearImage, VK_FORMAT_R8G8B8A8_UNORM, vk::Format::eR8G8B8A8Unorm, vk::ImageAspectFlagBits::eColor)->Unit(benchmark::kMillisecond)->MeasureProcessCPUTime(); BENCHMARK_CAPTURE(ClearImage, VK_FORMAT_R32_SFLOAT, vk::Format::eR32Sfloat, vk::ImageAspectFlagBits::eColor)->Unit(benchmark::kMillisecond)->MeasureProcessCPUTime(); BENCHMARK_CAPTURE(ClearImage, VK_FORMAT_D32_SFLOAT, vk::Format::eD32Sfloat, vk::ImageAspectFlagBits::eDepth)->Unit(benchmark::kMillisecond)->MeasureProcessCPUTime();