xref: /aosp_15_r20/external/swiftshader/tests/VulkanBenchmarks/ComputeBenchmarks.cpp (revision 03ce13f70fcc45d86ee91b7ee4cab1936a95046e)
1*03ce13f7SAndroid Build Coastguard Worker // Copyright 2021 The SwiftShader Authors. All Rights Reserved.
2*03ce13f7SAndroid Build Coastguard Worker //
3*03ce13f7SAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
4*03ce13f7SAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
5*03ce13f7SAndroid Build Coastguard Worker // You may obtain a copy of the License at
6*03ce13f7SAndroid Build Coastguard Worker //
7*03ce13f7SAndroid Build Coastguard Worker //    http://www.apache.org/licenses/LICENSE-2.0
8*03ce13f7SAndroid Build Coastguard Worker //
9*03ce13f7SAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*03ce13f7SAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
11*03ce13f7SAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*03ce13f7SAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
13*03ce13f7SAndroid Build Coastguard Worker // limitations under the License.
14*03ce13f7SAndroid Build Coastguard Worker 
15*03ce13f7SAndroid Build Coastguard Worker #include "Util.hpp"
16*03ce13f7SAndroid Build Coastguard Worker #include "VulkanTester.hpp"
17*03ce13f7SAndroid Build Coastguard Worker 
18*03ce13f7SAndroid Build Coastguard Worker #include "benchmark/benchmark.h"
19*03ce13f7SAndroid Build Coastguard Worker 
20*03ce13f7SAndroid Build Coastguard Worker #include <cmath>
21*03ce13f7SAndroid Build Coastguard Worker #include <cstring>
22*03ce13f7SAndroid Build Coastguard Worker #include <sstream>
23*03ce13f7SAndroid Build Coastguard Worker 
24*03ce13f7SAndroid Build Coastguard Worker // C++ reference implementation for single-threaded 'compute' operations.
25*03ce13f7SAndroid Build Coastguard Worker template<typename Init, typename Func>
CppCompute(benchmark::State & state,Init init,Func op)26*03ce13f7SAndroid Build Coastguard Worker void CppCompute(benchmark::State &state, Init init, Func op)
27*03ce13f7SAndroid Build Coastguard Worker {
28*03ce13f7SAndroid Build Coastguard Worker 	int64_t numElements = state.range(0);
29*03ce13f7SAndroid Build Coastguard Worker 	float *bufferIn = (float *)malloc(numElements * sizeof(float));
30*03ce13f7SAndroid Build Coastguard Worker 	float *bufferOut = (float *)malloc(numElements * sizeof(float));
31*03ce13f7SAndroid Build Coastguard Worker 
32*03ce13f7SAndroid Build Coastguard Worker 	for(int64_t i = 0; i < numElements; i++)
33*03ce13f7SAndroid Build Coastguard Worker 	{
34*03ce13f7SAndroid Build Coastguard Worker 		bufferIn[i] = init(i);
35*03ce13f7SAndroid Build Coastguard Worker 	}
36*03ce13f7SAndroid Build Coastguard Worker 
37*03ce13f7SAndroid Build Coastguard Worker 	for(auto _ : state)
38*03ce13f7SAndroid Build Coastguard Worker 	{
39*03ce13f7SAndroid Build Coastguard Worker 		for(int64_t i = 0; i < numElements; i++)
40*03ce13f7SAndroid Build Coastguard Worker 		{
41*03ce13f7SAndroid Build Coastguard Worker 			bufferOut[i] = op(bufferIn[i]);
42*03ce13f7SAndroid Build Coastguard Worker 		}
43*03ce13f7SAndroid Build Coastguard Worker 	}
44*03ce13f7SAndroid Build Coastguard Worker 
45*03ce13f7SAndroid Build Coastguard Worker 	free(bufferIn);
46*03ce13f7SAndroid Build Coastguard Worker 	free(bufferOut);
47*03ce13f7SAndroid Build Coastguard Worker }
48*03ce13f7SAndroid Build Coastguard Worker 
zero(int64_t i)49*03ce13f7SAndroid Build Coastguard Worker float zero(int64_t i)
50*03ce13f7SAndroid Build Coastguard Worker {
51*03ce13f7SAndroid Build Coastguard Worker 	return 0.0f;
52*03ce13f7SAndroid Build Coastguard Worker }
53*03ce13f7SAndroid Build Coastguard Worker 
one(int64_t i)54*03ce13f7SAndroid Build Coastguard Worker float one(int64_t i)
55*03ce13f7SAndroid Build Coastguard Worker {
56*03ce13f7SAndroid Build Coastguard Worker 	return 1.0f;
57*03ce13f7SAndroid Build Coastguard Worker }
58*03ce13f7SAndroid Build Coastguard Worker 
__anon1e3422c60102(float x) 59*03ce13f7SAndroid Build Coastguard Worker BENCHMARK_CAPTURE(CppCompute, mov, zero, [](float x) { return x; })->Arg(4 * 1024 * 1024)->Unit(benchmark::kMillisecond);
60*03ce13f7SAndroid Build Coastguard Worker BENCHMARK_CAPTURE(CppCompute, sqrt, one, sqrtf)->Arg(4 * 1024 * 1024)->Unit(benchmark::kMillisecond);
61*03ce13f7SAndroid Build Coastguard Worker BENCHMARK_CAPTURE(CppCompute, sin, zero, sinf)->Arg(4 * 1024 * 1024)->Unit(benchmark::kMillisecond);
62*03ce13f7SAndroid Build Coastguard Worker BENCHMARK_CAPTURE(CppCompute, cos, zero, cosf)->Arg(4 * 1024 * 1024)->Unit(benchmark::kMillisecond);
63*03ce13f7SAndroid Build Coastguard Worker BENCHMARK_CAPTURE(CppCompute, exp, zero, expf)->Arg(4 * 1024 * 1024)->Unit(benchmark::kMillisecond);
64*03ce13f7SAndroid Build Coastguard Worker BENCHMARK_CAPTURE(CppCompute, log, one, logf)->Arg(4 * 1024 * 1024)->Unit(benchmark::kMillisecond);
65*03ce13f7SAndroid Build Coastguard Worker 
66*03ce13f7SAndroid Build Coastguard Worker class ComputeBenchmark
67*03ce13f7SAndroid Build Coastguard Worker {
68*03ce13f7SAndroid Build Coastguard Worker protected:
ComputeBenchmark()69*03ce13f7SAndroid Build Coastguard Worker 	ComputeBenchmark()
70*03ce13f7SAndroid Build Coastguard Worker 	{
71*03ce13f7SAndroid Build Coastguard Worker 		tester.initialize();
72*03ce13f7SAndroid Build Coastguard Worker 	}
73*03ce13f7SAndroid Build Coastguard Worker 
74*03ce13f7SAndroid Build Coastguard Worker 	VulkanTester tester;
75*03ce13f7SAndroid Build Coastguard Worker };
76*03ce13f7SAndroid Build Coastguard Worker 
77*03ce13f7SAndroid Build Coastguard Worker // Base class for compute benchmarks that read from an input buffer and write to an
78*03ce13f7SAndroid Build Coastguard Worker // output buffer of the same length.
79*03ce13f7SAndroid Build Coastguard Worker class BufferToBufferComputeBenchmark : public ComputeBenchmark
80*03ce13f7SAndroid Build Coastguard Worker {
81*03ce13f7SAndroid Build Coastguard Worker public:
BufferToBufferComputeBenchmark(const benchmark::State & state)82*03ce13f7SAndroid Build Coastguard Worker 	BufferToBufferComputeBenchmark(const benchmark::State &state)
83*03ce13f7SAndroid Build Coastguard Worker 	    : state(state)
84*03ce13f7SAndroid Build Coastguard Worker 	{
85*03ce13f7SAndroid Build Coastguard Worker 		device = tester.getDevice();
86*03ce13f7SAndroid Build Coastguard Worker 	}
87*03ce13f7SAndroid Build Coastguard Worker 
~BufferToBufferComputeBenchmark()88*03ce13f7SAndroid Build Coastguard Worker 	virtual ~BufferToBufferComputeBenchmark()
89*03ce13f7SAndroid Build Coastguard Worker 	{
90*03ce13f7SAndroid Build Coastguard Worker 		device.destroyCommandPool(commandPool);
91*03ce13f7SAndroid Build Coastguard Worker 		device.destroyDescriptorPool(descriptorPool);
92*03ce13f7SAndroid Build Coastguard Worker 		device.destroyPipeline(pipeline);
93*03ce13f7SAndroid Build Coastguard Worker 		device.destroyDescriptorSetLayout(descriptorSetLayout);
94*03ce13f7SAndroid Build Coastguard Worker 		device.destroyBuffer(bufferIn);
95*03ce13f7SAndroid Build Coastguard Worker 		device.destroyBuffer(bufferOut);
96*03ce13f7SAndroid Build Coastguard Worker 		device.freeMemory(deviceMemory);
97*03ce13f7SAndroid Build Coastguard Worker 	}
98*03ce13f7SAndroid Build Coastguard Worker 
99*03ce13f7SAndroid Build Coastguard Worker 	void run();
100*03ce13f7SAndroid Build Coastguard Worker 
101*03ce13f7SAndroid Build Coastguard Worker protected:
102*03ce13f7SAndroid Build Coastguard Worker 	void initialize(const std::string &glslShader);
103*03ce13f7SAndroid Build Coastguard Worker 
104*03ce13f7SAndroid Build Coastguard Worker 	uint32_t localSizeX = 128;
105*03ce13f7SAndroid Build Coastguard Worker 	uint32_t localSizeY = 1;
106*03ce13f7SAndroid Build Coastguard Worker 	uint32_t localSizeZ = 1;
107*03ce13f7SAndroid Build Coastguard Worker 
108*03ce13f7SAndroid Build Coastguard Worker private:
109*03ce13f7SAndroid Build Coastguard Worker 	const benchmark::State &state;
110*03ce13f7SAndroid Build Coastguard Worker 
111*03ce13f7SAndroid Build Coastguard Worker 	// Weak references
112*03ce13f7SAndroid Build Coastguard Worker 	vk::Device device;
113*03ce13f7SAndroid Build Coastguard Worker 	vk::Queue queue;
114*03ce13f7SAndroid Build Coastguard Worker 	vk::CommandBuffer commandBuffer;
115*03ce13f7SAndroid Build Coastguard Worker 
116*03ce13f7SAndroid Build Coastguard Worker 	// Owned resources
117*03ce13f7SAndroid Build Coastguard Worker 	vk::CommandPool commandPool;
118*03ce13f7SAndroid Build Coastguard Worker 	vk::DescriptorPool descriptorPool;
119*03ce13f7SAndroid Build Coastguard Worker 	vk::Pipeline pipeline;
120*03ce13f7SAndroid Build Coastguard Worker 	vk::DescriptorSetLayout descriptorSetLayout;
121*03ce13f7SAndroid Build Coastguard Worker 	vk::DeviceMemory deviceMemory;
122*03ce13f7SAndroid Build Coastguard Worker 	vk::Buffer bufferIn;
123*03ce13f7SAndroid Build Coastguard Worker 	vk::Buffer bufferOut;
124*03ce13f7SAndroid Build Coastguard Worker };
125*03ce13f7SAndroid Build Coastguard Worker 
initialize(const std::string & glslShader)126*03ce13f7SAndroid Build Coastguard Worker void BufferToBufferComputeBenchmark::initialize(const std::string &glslShader)
127*03ce13f7SAndroid Build Coastguard Worker {
128*03ce13f7SAndroid Build Coastguard Worker 	auto code = Util::compileGLSLtoSPIRV(glslShader.c_str(), EShLanguage::EShLangCompute);
129*03ce13f7SAndroid Build Coastguard Worker 
130*03ce13f7SAndroid Build Coastguard Worker 	auto &device = tester.getDevice();
131*03ce13f7SAndroid Build Coastguard Worker 	auto &physicalDevice = tester.getPhysicalDevice();
132*03ce13f7SAndroid Build Coastguard Worker 	queue = device.getQueue(0, 0);  // TODO: Don't assume this queue can do compute.
133*03ce13f7SAndroid Build Coastguard Worker 
134*03ce13f7SAndroid Build Coastguard Worker 	size_t numElements = state.range(0);
135*03ce13f7SAndroid Build Coastguard Worker 	size_t inOffset = 0;
136*03ce13f7SAndroid Build Coastguard Worker 	size_t outOffset = numElements;
137*03ce13f7SAndroid Build Coastguard Worker 	size_t buffersTotalElements = 2 * numElements;
138*03ce13f7SAndroid Build Coastguard Worker 	size_t buffersSize = sizeof(uint32_t) * buffersTotalElements;
139*03ce13f7SAndroid Build Coastguard Worker 
140*03ce13f7SAndroid Build Coastguard Worker 	// TODO: vk::MemoryRequirements memoryRequirements = device.getBufferMemoryRequirements(buffer);
141*03ce13f7SAndroid Build Coastguard Worker 	vk::MemoryAllocateInfo allocateInfo;
142*03ce13f7SAndroid Build Coastguard Worker 	allocateInfo.allocationSize = buffersSize;  // TODO: memoryRequirements.size
143*03ce13f7SAndroid Build Coastguard Worker 	allocateInfo.memoryTypeIndex = 0;           // TODO: memoryRequirements.memoryTypeBits
144*03ce13f7SAndroid Build Coastguard Worker 	deviceMemory = device.allocateMemory(allocateInfo);
145*03ce13f7SAndroid Build Coastguard Worker 
146*03ce13f7SAndroid Build Coastguard Worker 	uint32_t *buffers = (uint32_t *)device.mapMemory(deviceMemory, 0, buffersSize);
147*03ce13f7SAndroid Build Coastguard Worker 	memset(buffers, 0, buffersSize);
148*03ce13f7SAndroid Build Coastguard Worker 
149*03ce13f7SAndroid Build Coastguard Worker 	for(size_t i = 0; i < numElements; i++)
150*03ce13f7SAndroid Build Coastguard Worker 	{
151*03ce13f7SAndroid Build Coastguard Worker 		buffers[inOffset + i] = (uint32_t)i;
152*03ce13f7SAndroid Build Coastguard Worker 	}
153*03ce13f7SAndroid Build Coastguard Worker 
154*03ce13f7SAndroid Build Coastguard Worker 	device.unmapMemory(deviceMemory);
155*03ce13f7SAndroid Build Coastguard Worker 	buffers = nullptr;
156*03ce13f7SAndroid Build Coastguard Worker 
157*03ce13f7SAndroid Build Coastguard Worker 	vk::BufferCreateInfo bufferCreateInfo({}, sizeof(uint32_t) * numElements, vk::BufferUsageFlagBits::eStorageBuffer);
158*03ce13f7SAndroid Build Coastguard Worker 	bufferIn = device.createBuffer(bufferCreateInfo);
159*03ce13f7SAndroid Build Coastguard Worker 	device.bindBufferMemory(bufferIn, deviceMemory, sizeof(uint32_t) * inOffset);
160*03ce13f7SAndroid Build Coastguard Worker 
161*03ce13f7SAndroid Build Coastguard Worker 	bufferOut = device.createBuffer(bufferCreateInfo);
162*03ce13f7SAndroid Build Coastguard Worker 	device.bindBufferMemory(bufferOut, deviceMemory, sizeof(uint32_t) * outOffset);
163*03ce13f7SAndroid Build Coastguard Worker 
164*03ce13f7SAndroid Build Coastguard Worker 	vk::ShaderModuleCreateInfo moduleCreateInfo;
165*03ce13f7SAndroid Build Coastguard Worker 	moduleCreateInfo.codeSize = code.size() * sizeof(uint32_t);
166*03ce13f7SAndroid Build Coastguard Worker 	moduleCreateInfo.pCode = (uint32_t *)code.data();
167*03ce13f7SAndroid Build Coastguard Worker 	vk::ShaderModule shaderModule = device.createShaderModule(moduleCreateInfo);
168*03ce13f7SAndroid Build Coastguard Worker 
169*03ce13f7SAndroid Build Coastguard Worker 	vk::DescriptorSetLayoutBinding in;
170*03ce13f7SAndroid Build Coastguard Worker 	in.binding = 0;
171*03ce13f7SAndroid Build Coastguard Worker 	in.descriptorCount = 1;
172*03ce13f7SAndroid Build Coastguard Worker 	in.descriptorType = vk::DescriptorType::eStorageBuffer;
173*03ce13f7SAndroid Build Coastguard Worker 	in.stageFlags = vk::ShaderStageFlagBits::eCompute;
174*03ce13f7SAndroid Build Coastguard Worker 
175*03ce13f7SAndroid Build Coastguard Worker 	vk::DescriptorSetLayoutBinding out;
176*03ce13f7SAndroid Build Coastguard Worker 	out.binding = 1;
177*03ce13f7SAndroid Build Coastguard Worker 	out.descriptorCount = 1;
178*03ce13f7SAndroid Build Coastguard Worker 	out.descriptorType = vk::DescriptorType::eStorageBuffer;
179*03ce13f7SAndroid Build Coastguard Worker 	out.stageFlags = vk::ShaderStageFlagBits::eCompute;
180*03ce13f7SAndroid Build Coastguard Worker 
181*03ce13f7SAndroid Build Coastguard Worker 	std::vector<vk::DescriptorSetLayoutBinding> setLayoutBindings = { in, out };
182*03ce13f7SAndroid Build Coastguard Worker 	vk::DescriptorSetLayoutCreateInfo layoutInfo;
183*03ce13f7SAndroid Build Coastguard Worker 	layoutInfo.bindingCount = static_cast<uint32_t>(setLayoutBindings.size());
184*03ce13f7SAndroid Build Coastguard Worker 	layoutInfo.pBindings = setLayoutBindings.data();
185*03ce13f7SAndroid Build Coastguard Worker 	descriptorSetLayout = device.createDescriptorSetLayout(layoutInfo);
186*03ce13f7SAndroid Build Coastguard Worker 
187*03ce13f7SAndroid Build Coastguard Worker 	vk::PipelineLayoutCreateInfo pipelineLayoutCreateInfo;
188*03ce13f7SAndroid Build Coastguard Worker 	pipelineLayoutCreateInfo.setLayoutCount = 1;
189*03ce13f7SAndroid Build Coastguard Worker 	pipelineLayoutCreateInfo.pSetLayouts = &descriptorSetLayout;
190*03ce13f7SAndroid Build Coastguard Worker 	vk::PipelineLayout pipelineLayout = device.createPipelineLayout(pipelineLayoutCreateInfo);
191*03ce13f7SAndroid Build Coastguard Worker 
192*03ce13f7SAndroid Build Coastguard Worker 	vk::ComputePipelineCreateInfo computePipelineCreateInfo;
193*03ce13f7SAndroid Build Coastguard Worker 	computePipelineCreateInfo.layout = pipelineLayout;
194*03ce13f7SAndroid Build Coastguard Worker 	computePipelineCreateInfo.stage.stage = vk::ShaderStageFlagBits::eCompute;
195*03ce13f7SAndroid Build Coastguard Worker 	computePipelineCreateInfo.stage.module = shaderModule;
196*03ce13f7SAndroid Build Coastguard Worker 	computePipelineCreateInfo.stage.pName = "main";
197*03ce13f7SAndroid Build Coastguard Worker 	pipeline = device.createComputePipeline({}, computePipelineCreateInfo).value;
198*03ce13f7SAndroid Build Coastguard Worker 
199*03ce13f7SAndroid Build Coastguard Worker 	// "A shader module can be destroyed while pipelines created using its shaders are still in use."
200*03ce13f7SAndroid Build Coastguard Worker 	device.destroyShaderModule(shaderModule);
201*03ce13f7SAndroid Build Coastguard Worker 
202*03ce13f7SAndroid Build Coastguard Worker 	std::array<vk::DescriptorPoolSize, 1> poolSizes = {};
203*03ce13f7SAndroid Build Coastguard Worker 	poolSizes[0].type = vk::DescriptorType::eStorageBuffer;
204*03ce13f7SAndroid Build Coastguard Worker 	poolSizes[0].descriptorCount = 2;
205*03ce13f7SAndroid Build Coastguard Worker 	vk::DescriptorPoolCreateInfo descriptorPoolCreateInfo;
206*03ce13f7SAndroid Build Coastguard Worker 	descriptorPoolCreateInfo.maxSets = 1;
207*03ce13f7SAndroid Build Coastguard Worker 	descriptorPoolCreateInfo.poolSizeCount = static_cast<uint32_t>(poolSizes.size());
208*03ce13f7SAndroid Build Coastguard Worker 	descriptorPoolCreateInfo.pPoolSizes = poolSizes.data();
209*03ce13f7SAndroid Build Coastguard Worker 
210*03ce13f7SAndroid Build Coastguard Worker 	descriptorPool = device.createDescriptorPool(descriptorPoolCreateInfo);
211*03ce13f7SAndroid Build Coastguard Worker 
212*03ce13f7SAndroid Build Coastguard Worker 	vk::DescriptorSetAllocateInfo descriptorSetAllocateInfo;
213*03ce13f7SAndroid Build Coastguard Worker 	descriptorSetAllocateInfo.descriptorPool = descriptorPool;
214*03ce13f7SAndroid Build Coastguard Worker 	descriptorSetAllocateInfo.descriptorSetCount = 1;
215*03ce13f7SAndroid Build Coastguard Worker 	descriptorSetAllocateInfo.pSetLayouts = &descriptorSetLayout;
216*03ce13f7SAndroid Build Coastguard Worker 	auto descriptorSets = device.allocateDescriptorSets(descriptorSetAllocateInfo);
217*03ce13f7SAndroid Build Coastguard Worker 
218*03ce13f7SAndroid Build Coastguard Worker 	vk::DescriptorBufferInfo inBufferInfo;
219*03ce13f7SAndroid Build Coastguard Worker 	inBufferInfo.buffer = bufferIn;
220*03ce13f7SAndroid Build Coastguard Worker 	inBufferInfo.offset = 0;
221*03ce13f7SAndroid Build Coastguard Worker 	inBufferInfo.range = VK_WHOLE_SIZE;
222*03ce13f7SAndroid Build Coastguard Worker 
223*03ce13f7SAndroid Build Coastguard Worker 	vk::DescriptorBufferInfo outBufferInfo;
224*03ce13f7SAndroid Build Coastguard Worker 	outBufferInfo.buffer = bufferOut;
225*03ce13f7SAndroid Build Coastguard Worker 	outBufferInfo.offset = 0;
226*03ce13f7SAndroid Build Coastguard Worker 	outBufferInfo.range = VK_WHOLE_SIZE;
227*03ce13f7SAndroid Build Coastguard Worker 
228*03ce13f7SAndroid Build Coastguard Worker 	std::array<vk::WriteDescriptorSet, 2> descriptorWrites = {};
229*03ce13f7SAndroid Build Coastguard Worker 
230*03ce13f7SAndroid Build Coastguard Worker 	descriptorWrites[0].dstSet = descriptorSets[0];
231*03ce13f7SAndroid Build Coastguard Worker 	descriptorWrites[0].dstBinding = 0;
232*03ce13f7SAndroid Build Coastguard Worker 	descriptorWrites[0].dstArrayElement = 0;
233*03ce13f7SAndroid Build Coastguard Worker 	descriptorWrites[0].descriptorType = vk::DescriptorType::eStorageBuffer;
234*03ce13f7SAndroid Build Coastguard Worker 	descriptorWrites[0].descriptorCount = 1;
235*03ce13f7SAndroid Build Coastguard Worker 	descriptorWrites[0].pBufferInfo = &inBufferInfo;
236*03ce13f7SAndroid Build Coastguard Worker 
237*03ce13f7SAndroid Build Coastguard Worker 	descriptorWrites[1].dstSet = descriptorSets[0];
238*03ce13f7SAndroid Build Coastguard Worker 	descriptorWrites[1].dstBinding = 1;
239*03ce13f7SAndroid Build Coastguard Worker 	descriptorWrites[1].dstArrayElement = 0;
240*03ce13f7SAndroid Build Coastguard Worker 	descriptorWrites[1].descriptorType = vk::DescriptorType::eStorageBuffer;
241*03ce13f7SAndroid Build Coastguard Worker 	descriptorWrites[1].descriptorCount = 1;
242*03ce13f7SAndroid Build Coastguard Worker 	descriptorWrites[1].pBufferInfo = &outBufferInfo;
243*03ce13f7SAndroid Build Coastguard Worker 
244*03ce13f7SAndroid Build Coastguard Worker 	device.updateDescriptorSets(static_cast<uint32_t>(descriptorWrites.size()), descriptorWrites.data(), 0, nullptr);
245*03ce13f7SAndroid Build Coastguard Worker 
246*03ce13f7SAndroid Build Coastguard Worker 	vk::CommandPoolCreateInfo commandPoolCreateInfo;
247*03ce13f7SAndroid Build Coastguard Worker 	commandPoolCreateInfo.queueFamilyIndex = 0;  // TODO: Don't assume queue family 0 can do compute.
248*03ce13f7SAndroid Build Coastguard Worker 	commandPoolCreateInfo.flags = vk::CommandPoolCreateFlagBits::eResetCommandBuffer;
249*03ce13f7SAndroid Build Coastguard Worker 	commandPool = device.createCommandPool(commandPoolCreateInfo);
250*03ce13f7SAndroid Build Coastguard Worker 
251*03ce13f7SAndroid Build Coastguard Worker 	vk::CommandBufferAllocateInfo commandBufferAllocateInfo;
252*03ce13f7SAndroid Build Coastguard Worker 	commandBufferAllocateInfo.commandPool = commandPool;
253*03ce13f7SAndroid Build Coastguard Worker 	commandBufferAllocateInfo.commandBufferCount = 1;
254*03ce13f7SAndroid Build Coastguard Worker 	commandBufferAllocateInfo.level = vk::CommandBufferLevel::ePrimary;
255*03ce13f7SAndroid Build Coastguard Worker 	auto commandBuffers = device.allocateCommandBuffers(commandBufferAllocateInfo);
256*03ce13f7SAndroid Build Coastguard Worker 
257*03ce13f7SAndroid Build Coastguard Worker 	// Record the command buffer
258*03ce13f7SAndroid Build Coastguard Worker 	commandBuffer = commandBuffers[0];
259*03ce13f7SAndroid Build Coastguard Worker 
260*03ce13f7SAndroid Build Coastguard Worker 	vk::CommandBufferBeginInfo commandBufferBeginInfo;
261*03ce13f7SAndroid Build Coastguard Worker 	commandBuffer.begin(commandBufferBeginInfo);
262*03ce13f7SAndroid Build Coastguard Worker 
263*03ce13f7SAndroid Build Coastguard Worker 	commandBuffer.bindPipeline(vk::PipelineBindPoint::eCompute, pipeline);
264*03ce13f7SAndroid Build Coastguard Worker 	commandBuffer.bindDescriptorSets(vk::PipelineBindPoint::eCompute, pipelineLayout, 0, 1, &descriptorSets[0], 0, nullptr);
265*03ce13f7SAndroid Build Coastguard Worker 
266*03ce13f7SAndroid Build Coastguard Worker 	commandBuffer.dispatch((uint32_t)(numElements / localSizeX), 1, 1);
267*03ce13f7SAndroid Build Coastguard Worker 
268*03ce13f7SAndroid Build Coastguard Worker 	commandBuffer.end();
269*03ce13f7SAndroid Build Coastguard Worker 
270*03ce13f7SAndroid Build Coastguard Worker 	// Destroy objects we don't have to hold on to after command buffer recording.
271*03ce13f7SAndroid Build Coastguard Worker 	// "A VkPipelineLayout object must not be destroyed while any command buffer that uses it is in the recording state."
272*03ce13f7SAndroid Build Coastguard Worker 	device.destroyPipelineLayout(pipelineLayout);
273*03ce13f7SAndroid Build Coastguard Worker }
274*03ce13f7SAndroid Build Coastguard Worker 
run()275*03ce13f7SAndroid Build Coastguard Worker void BufferToBufferComputeBenchmark::run()
276*03ce13f7SAndroid Build Coastguard Worker {
277*03ce13f7SAndroid Build Coastguard Worker 	vk::SubmitInfo submitInfo;
278*03ce13f7SAndroid Build Coastguard Worker 	submitInfo.commandBufferCount = 1;
279*03ce13f7SAndroid Build Coastguard Worker 	submitInfo.pCommandBuffers = &commandBuffer;
280*03ce13f7SAndroid Build Coastguard Worker 	queue.submit(submitInfo);
281*03ce13f7SAndroid Build Coastguard Worker 	queue.waitIdle();
282*03ce13f7SAndroid Build Coastguard Worker }
283*03ce13f7SAndroid Build Coastguard Worker 
284*03ce13f7SAndroid Build Coastguard Worker // Performs an operation `op` on each element.
285*03ce13f7SAndroid Build Coastguard Worker class ComputeOp : public BufferToBufferComputeBenchmark
286*03ce13f7SAndroid Build Coastguard Worker {
287*03ce13f7SAndroid Build Coastguard Worker public:
ComputeOp(const benchmark::State & state,const char * op,const char * precision)288*03ce13f7SAndroid Build Coastguard Worker 	ComputeOp(const benchmark::State &state, const char *op, const char *precision)
289*03ce13f7SAndroid Build Coastguard Worker 	    : BufferToBufferComputeBenchmark(state)
290*03ce13f7SAndroid Build Coastguard Worker 	{
291*03ce13f7SAndroid Build Coastguard Worker 		std::stringstream src;
292*03ce13f7SAndroid Build Coastguard Worker 		src << R"(#version 450
293*03ce13f7SAndroid Build Coastguard Worker 			layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
294*03ce13f7SAndroid Build Coastguard Worker 			layout(binding = 0, std430) buffer InBuffer
295*03ce13f7SAndroid Build Coastguard Worker 			{
296*03ce13f7SAndroid Build Coastguard Worker 				float Data[];
297*03ce13f7SAndroid Build Coastguard Worker 			} In;
298*03ce13f7SAndroid Build Coastguard Worker 			layout(binding = 1, std430) buffer OutBuffer
299*03ce13f7SAndroid Build Coastguard Worker 			{
300*03ce13f7SAndroid Build Coastguard Worker 				float Data[];
301*03ce13f7SAndroid Build Coastguard Worker 			} Out;
302*03ce13f7SAndroid Build Coastguard Worker 			void main()
303*03ce13f7SAndroid Build Coastguard Worker 			{
304*03ce13f7SAndroid Build Coastguard Worker 				)"
305*03ce13f7SAndroid Build Coastguard Worker 		    << precision << R"( float x = In.Data[gl_GlobalInvocationID.x];
306*03ce13f7SAndroid Build Coastguard Worker 				Out.Data[gl_GlobalInvocationID.x] = )"
307*03ce13f7SAndroid Build Coastguard Worker 		    << op << R"( (x);
308*03ce13f7SAndroid Build Coastguard Worker 			})";
309*03ce13f7SAndroid Build Coastguard Worker 
310*03ce13f7SAndroid Build Coastguard Worker 		initialize(src.str());
311*03ce13f7SAndroid Build Coastguard Worker 	}
312*03ce13f7SAndroid Build Coastguard Worker };
313*03ce13f7SAndroid Build Coastguard Worker 
Compute(benchmark::State & state,const char * op,const char * precision="highp")314*03ce13f7SAndroid Build Coastguard Worker static void Compute(benchmark::State &state, const char *op, const char *precision = "highp")
315*03ce13f7SAndroid Build Coastguard Worker {
316*03ce13f7SAndroid Build Coastguard Worker 	ComputeOp benchmark(state, op, precision);
317*03ce13f7SAndroid Build Coastguard Worker 
318*03ce13f7SAndroid Build Coastguard Worker 	// Execute once to have the Reactor routine generated.
319*03ce13f7SAndroid Build Coastguard Worker 	benchmark.run();
320*03ce13f7SAndroid Build Coastguard Worker 
321*03ce13f7SAndroid Build Coastguard Worker 	for(auto _ : state)
322*03ce13f7SAndroid Build Coastguard Worker 	{
323*03ce13f7SAndroid Build Coastguard Worker 		benchmark.run();
324*03ce13f7SAndroid Build Coastguard Worker 	}
325*03ce13f7SAndroid Build Coastguard Worker }
326*03ce13f7SAndroid Build Coastguard Worker 
327*03ce13f7SAndroid Build Coastguard Worker BENCHMARK_CAPTURE(Compute, mov, "")->RangeMultiplier(2)->Range(128, 4 * 1024 * 1024)->Unit(benchmark::kMillisecond)->MeasureProcessCPUTime();
328*03ce13f7SAndroid Build Coastguard Worker 
329*03ce13f7SAndroid Build Coastguard Worker BENCHMARK_CAPTURE(Compute, sqrt_highp, "sqrt", "highp")->Arg(4 * 1024 * 1024)->Unit(benchmark::kMillisecond)->MeasureProcessCPUTime();
330*03ce13f7SAndroid Build Coastguard Worker BENCHMARK_CAPTURE(Compute, sin_highp, "sin", "highp")->Arg(4 * 1024 * 1024)->Unit(benchmark::kMillisecond)->MeasureProcessCPUTime();
331*03ce13f7SAndroid Build Coastguard Worker BENCHMARK_CAPTURE(Compute, cos_highp, "cos", "highp")->Arg(4 * 1024 * 1024)->Unit(benchmark::kMillisecond)->MeasureProcessCPUTime();
332*03ce13f7SAndroid Build Coastguard Worker BENCHMARK_CAPTURE(Compute, exp_highp, "exp", "highp")->Arg(4 * 1024 * 1024)->Unit(benchmark::kMillisecond)->MeasureProcessCPUTime();
333*03ce13f7SAndroid Build Coastguard Worker BENCHMARK_CAPTURE(Compute, log_highp, "log", "highp")->Arg(4 * 1024 * 1024)->Unit(benchmark::kMillisecond)->MeasureProcessCPUTime();
334*03ce13f7SAndroid Build Coastguard Worker 
335*03ce13f7SAndroid Build Coastguard Worker BENCHMARK_CAPTURE(Compute, sqrt_mediump, "sqrt", "mediump")->Arg(4 * 1024 * 1024)->Unit(benchmark::kMillisecond)->MeasureProcessCPUTime();
336*03ce13f7SAndroid Build Coastguard Worker BENCHMARK_CAPTURE(Compute, sin_mediump, "sin", "mediump")->Arg(4 * 1024 * 1024)->Unit(benchmark::kMillisecond)->MeasureProcessCPUTime();
337*03ce13f7SAndroid Build Coastguard Worker BENCHMARK_CAPTURE(Compute, cos_mediump, "cos", "mediump")->Arg(4 * 1024 * 1024)->Unit(benchmark::kMillisecond)->MeasureProcessCPUTime();
338*03ce13f7SAndroid Build Coastguard Worker BENCHMARK_CAPTURE(Compute, exp_mediump, "exp", "mediump")->Arg(4 * 1024 * 1024)->Unit(benchmark::kMillisecond)->MeasureProcessCPUTime();
339*03ce13f7SAndroid Build Coastguard Worker BENCHMARK_CAPTURE(Compute, log_mediump, "log", "mediump")->Arg(4 * 1024 * 1024)->Unit(benchmark::kMillisecond)->MeasureProcessCPUTime();