1 // Copyright 2018 The ANGLE Project Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 //
5 // VulkanCommandBufferPerf:
6 // Performance benchmark for Vulkan Primary/Secondary Command Buffer implementations.
7 // Can run just these tests by adding "--gtest_filter=VulkanCommandBufferPerfTest*"
8 // option to angle_white_box_perftests.
9 // When running on Android with run_angle_white_box_perftests, use "-v" option.
10
11 #include "ANGLEPerfTest.h"
12 #include "common/platform.h"
13 #include "test_utils/third_party/vulkan_command_buffer_utils.h"
14
15 #if defined(ANDROID)
16 # define NUM_CMD_BUFFERS 1000
17 // Android devices tend to be slower so only do 10 frames to avoid timeout
18 # define NUM_FRAMES 10
19 #else
20 # define NUM_CMD_BUFFERS 1000
21 # define NUM_FRAMES 100
22 #endif
23
24 // These are minimal shaders used to submit trivial draw commands to command
25 // buffers so that we can create large batches of cmd buffers with consistent
26 // draw patterns but size/type of cmd buffers can be varied to test cmd buffer
27 // differences across devices.
28 constexpr char kVertShaderText[] = R"(
29 #version 400
30 #extension GL_ARB_separate_shader_objects : enable
31 #extension GL_ARB_shading_language_420pack : enable
32 layout (std140, binding = 0) uniform bufferVals {
33 mat4 mvp;
34 } myBufferVals;
35 layout (location = 0) in vec4 pos;
36 layout (location = 1) in vec4 inColor;
37 layout (location = 0) out vec4 outColor;
38 void main() {
39 outColor = inColor;
40 gl_Position = myBufferVals.mvp * pos;
41 })";
42
43 constexpr char kFragShaderText[] = R"(
44 #version 400
45 #extension GL_ARB_separate_shader_objects : enable
46 #extension GL_ARB_shading_language_420pack : enable
47 layout (location = 0) in vec4 color;
48 layout (location = 0) out vec4 outColor;
49 void main() {
50 outColor = color;
51 })";
52
53 using CommandBufferImpl = void (*)(sample_info &info,
54 VkClearValue *clear_values,
55 VkFence drawFence,
56 VkSemaphore imageAcquiredSemaphore,
57 int numBuffers);
58
59 struct CommandBufferTestParams
60 {
61 CommandBufferImpl CBImplementation;
62 std::string story;
63 int frames = NUM_FRAMES;
64 int buffers = NUM_CMD_BUFFERS;
65 };
66
67 class VulkanCommandBufferPerfTest : public ANGLEPerfTest,
68 public ::testing::WithParamInterface<CommandBufferTestParams>
69 {
70 public:
71 VulkanCommandBufferPerfTest();
72
73 void SetUp() override;
74 void TearDown() override;
75 void step() override;
76
77 private:
78 VkClearValue mClearValues[2] = {};
79 VkSemaphore mImageAcquiredSemaphore = VK_NULL_HANDLE;
80 VkFence mDrawFence = VK_NULL_HANDLE;
81
82 VkResult res = VK_NOT_READY;
83 const bool mDepthPresent = true;
84 struct sample_info mInfo = {};
85 std::string mSampleTitle;
86 CommandBufferImpl mCBImplementation = nullptr;
87 int mFrames = 0;
88 int mBuffers = 0;
89 };
90
VulkanCommandBufferPerfTest()91 VulkanCommandBufferPerfTest::VulkanCommandBufferPerfTest()
92 : ANGLEPerfTest("VulkanCommandBufferPerfTest", "", GetParam().story, GetParam().frames)
93 {
94 mInfo = {};
95 mSampleTitle = "Draw Textured Cube";
96 mCBImplementation = GetParam().CBImplementation;
97 mFrames = GetParam().frames;
98 mBuffers = GetParam().buffers;
99 }
100
SetUp()101 void VulkanCommandBufferPerfTest::SetUp()
102 {
103 init_global_layer_properties(mInfo);
104 init_instance_extension_names(mInfo);
105 init_device_extension_names(mInfo);
106 init_instance(mInfo, mSampleTitle.c_str());
107 init_enumerate_device(mInfo);
108 init_window_size(mInfo, 500, 500);
109 init_connection(mInfo);
110 init_window(mInfo);
111 init_swapchain_extension(mInfo);
112 init_device(mInfo);
113
114 init_command_pool(mInfo, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT);
115 init_command_buffer(mInfo); // Primary command buffer to hold secondaries
116 init_command_buffer_array(mInfo, mBuffers); // Array of primary command buffers
117 init_command_buffer2_array(mInfo, mBuffers); // Array containing all secondary buffers
118 init_device_queue(mInfo);
119 init_swap_chain(mInfo);
120 init_depth_buffer(mInfo);
121 init_uniform_buffer(mInfo);
122 init_descriptor_and_pipeline_layouts(mInfo, false);
123 init_renderpass(mInfo, mDepthPresent);
124 init_shaders(mInfo, kVertShaderText, kFragShaderText);
125 init_framebuffers(mInfo, mDepthPresent);
126 init_vertex_buffer(mInfo, g_vb_solid_face_colors_Data, sizeof(g_vb_solid_face_colors_Data),
127 sizeof(g_vb_solid_face_colors_Data[0]), false);
128 init_descriptor_pool(mInfo, false);
129 init_descriptor_set(mInfo);
130 init_pipeline_cache(mInfo);
131 init_pipeline(mInfo, mDepthPresent);
132
133 mClearValues[0].color.float32[0] = 0.2f;
134 mClearValues[0].color.float32[1] = 0.2f;
135 mClearValues[0].color.float32[2] = 0.2f;
136 mClearValues[0].color.float32[3] = 0.2f;
137 mClearValues[1].depthStencil.depth = 1.0f;
138 mClearValues[1].depthStencil.stencil = 0;
139
140 VkSemaphoreCreateInfo imageAcquiredSemaphoreCreateInfo;
141 imageAcquiredSemaphoreCreateInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
142 imageAcquiredSemaphoreCreateInfo.pNext = NULL;
143 imageAcquiredSemaphoreCreateInfo.flags = 0;
144 res = vkCreateSemaphore(mInfo.device, &imageAcquiredSemaphoreCreateInfo, NULL,
145 &mImageAcquiredSemaphore);
146 ASSERT_EQ(VK_SUCCESS, res);
147
148 VkFenceCreateInfo fenceInfo;
149 fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
150 fenceInfo.pNext = NULL;
151 fenceInfo.flags = 0;
152 res = vkCreateFence(mInfo.device, &fenceInfo, NULL, &mDrawFence);
153 ASSERT_EQ(VK_SUCCESS, res);
154 }
155
step()156 void VulkanCommandBufferPerfTest::step()
157 {
158 for (int x = 0; x < mFrames; x++)
159 {
160 mInfo.current_buffer = x % mInfo.swapchainImageCount;
161
162 // Get the index of the next available swapchain image:
163 res = vkAcquireNextImageKHR(mInfo.device, mInfo.swap_chain, UINT64_MAX,
164 mImageAcquiredSemaphore, VK_NULL_HANDLE, &mInfo.current_buffer);
165 // Deal with the VK_SUBOPTIMAL_KHR and VK_ERROR_OUT_OF_DATE_KHR
166 // return codes
167 ASSERT_EQ(VK_SUCCESS, res);
168 mCBImplementation(mInfo, mClearValues, mDrawFence, mImageAcquiredSemaphore, mBuffers);
169 }
170 }
171
TearDown()172 void VulkanCommandBufferPerfTest::TearDown()
173 {
174 vkDestroySemaphore(mInfo.device, mImageAcquiredSemaphore, NULL);
175 vkDestroyFence(mInfo.device, mDrawFence, NULL);
176 destroy_pipeline(mInfo);
177 destroy_pipeline_cache(mInfo);
178 destroy_descriptor_pool(mInfo);
179 destroy_vertex_buffer(mInfo);
180 destroy_framebuffers(mInfo);
181 destroy_shaders(mInfo);
182 destroy_renderpass(mInfo);
183 destroy_descriptor_and_pipeline_layouts(mInfo);
184 destroy_uniform_buffer(mInfo);
185 destroy_depth_buffer(mInfo);
186 destroy_swap_chain(mInfo);
187 destroy_command_buffer2_array(mInfo, mBuffers);
188 destroy_command_buffer_array(mInfo, mBuffers);
189 destroy_command_buffer(mInfo);
190 destroy_command_pool(mInfo);
191 destroy_device(mInfo);
192 destroy_window(mInfo);
193 destroy_instance(mInfo);
194 ANGLEPerfTest::TearDown();
195 }
196
197 // Common code to present image used by all tests
Present(sample_info & info,VkFence drawFence)198 void Present(sample_info &info, VkFence drawFence)
199 {
200 // Now present the image in the window
201
202 VkPresentInfoKHR present;
203 present.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
204 present.pNext = NULL;
205 present.swapchainCount = 1;
206 present.pSwapchains = &info.swap_chain;
207 present.pImageIndices = &info.current_buffer;
208 present.pWaitSemaphores = NULL;
209 present.waitSemaphoreCount = 0;
210 present.pResults = NULL;
211
212 // Make sure command buffer is finished before presenting
213 VkResult res;
214 do
215 {
216 res = vkWaitForFences(info.device, 1, &drawFence, VK_TRUE, FENCE_TIMEOUT);
217 } while (res == VK_TIMEOUT);
218 vkResetFences(info.device, 1, &drawFence);
219
220 ASSERT_EQ(VK_SUCCESS, res);
221 res = vkQueuePresentKHR(info.present_queue, &present);
222 ASSERT_EQ(VK_SUCCESS, res);
223 }
224
225 // 100 separate primary cmd buffers, each with 1 Draw
PrimaryCommandBufferBenchmarkHundredIndividual(sample_info & info,VkClearValue * clear_values,VkFence drawFence,VkSemaphore imageAcquiredSemaphore,int numBuffers)226 void PrimaryCommandBufferBenchmarkHundredIndividual(sample_info &info,
227 VkClearValue *clear_values,
228 VkFence drawFence,
229 VkSemaphore imageAcquiredSemaphore,
230 int numBuffers)
231 {
232 VkResult res;
233
234 VkRenderPassBeginInfo rpBegin;
235 rpBegin.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
236 rpBegin.pNext = NULL;
237 rpBegin.renderPass = info.render_pass;
238 rpBegin.framebuffer = info.framebuffers[info.current_buffer];
239 rpBegin.renderArea.offset.x = 0;
240 rpBegin.renderArea.offset.y = 0;
241 rpBegin.renderArea.extent.width = info.width;
242 rpBegin.renderArea.extent.height = info.height;
243 rpBegin.clearValueCount = 2;
244 rpBegin.pClearValues = clear_values;
245
246 VkCommandBufferBeginInfo cmdBufferInfo = {};
247 cmdBufferInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
248 cmdBufferInfo.pNext = NULL;
249 cmdBufferInfo.flags = 0;
250 cmdBufferInfo.pInheritanceInfo = NULL;
251
252 for (int x = 0; x < numBuffers; x++)
253 {
254 vkBeginCommandBuffer(info.cmds[x], &cmdBufferInfo);
255 vkCmdBeginRenderPass(info.cmds[x], &rpBegin, VK_SUBPASS_CONTENTS_INLINE);
256 vkCmdBindPipeline(info.cmds[x], VK_PIPELINE_BIND_POINT_GRAPHICS, info.pipeline);
257 vkCmdBindDescriptorSets(info.cmds[x], VK_PIPELINE_BIND_POINT_GRAPHICS, info.pipeline_layout,
258 0, NUM_DESCRIPTOR_SETS, info.desc_set.data(), 0, NULL);
259
260 const VkDeviceSize offsets[1] = {0};
261 vkCmdBindVertexBuffers(info.cmds[x], 0, 1, &info.vertex_buffer.buf, offsets);
262
263 init_viewports_array(info, x);
264 init_scissors_array(info, x);
265
266 vkCmdDraw(info.cmds[x], 0, 1, 0, 0);
267 vkCmdEndRenderPass(info.cmds[x]);
268 res = vkEndCommandBuffer(info.cmds[x]);
269 ASSERT_EQ(VK_SUCCESS, res);
270 }
271
272 VkPipelineStageFlags pipe_stage_flags = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
273 VkSubmitInfo submitInfo[1] = {};
274 submitInfo[0].pNext = NULL;
275 submitInfo[0].sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
276 submitInfo[0].waitSemaphoreCount = 1;
277 submitInfo[0].pWaitSemaphores = &imageAcquiredSemaphore;
278 submitInfo[0].pWaitDstStageMask = &pipe_stage_flags;
279 submitInfo[0].commandBufferCount = numBuffers;
280 submitInfo[0].pCommandBuffers = info.cmds.data();
281 submitInfo[0].signalSemaphoreCount = 0;
282 submitInfo[0].pSignalSemaphores = NULL;
283
284 // Queue the command buffer for execution
285 res = vkQueueSubmit(info.graphics_queue, 1, submitInfo, drawFence);
286 ASSERT_EQ(VK_SUCCESS, res);
287
288 Present(info, drawFence);
289 }
290
291 // 100 of the same Draw cmds in the same primary cmd buffer
PrimaryCommandBufferBenchmarkOneWithOneHundred(sample_info & info,VkClearValue * clear_values,VkFence drawFence,VkSemaphore imageAcquiredSemaphore,int numBuffers)292 void PrimaryCommandBufferBenchmarkOneWithOneHundred(sample_info &info,
293 VkClearValue *clear_values,
294 VkFence drawFence,
295 VkSemaphore imageAcquiredSemaphore,
296 int numBuffers)
297 {
298 VkResult res;
299
300 VkRenderPassBeginInfo rpBegin;
301 rpBegin.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
302 rpBegin.pNext = NULL;
303 rpBegin.renderPass = info.render_pass;
304 rpBegin.framebuffer = info.framebuffers[info.current_buffer];
305 rpBegin.renderArea.offset.x = 0;
306 rpBegin.renderArea.offset.y = 0;
307 rpBegin.renderArea.extent.width = info.width;
308 rpBegin.renderArea.extent.height = info.height;
309 rpBegin.clearValueCount = 2;
310 rpBegin.pClearValues = clear_values;
311
312 VkCommandBufferBeginInfo cmdBufferInfo = {};
313 cmdBufferInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
314 cmdBufferInfo.pNext = NULL;
315 cmdBufferInfo.flags = 0;
316 cmdBufferInfo.pInheritanceInfo = NULL;
317
318 vkBeginCommandBuffer(info.cmd, &cmdBufferInfo);
319 for (int x = 0; x < numBuffers; x++)
320 {
321 vkCmdBeginRenderPass(info.cmd, &rpBegin, VK_SUBPASS_CONTENTS_INLINE);
322 vkCmdBindPipeline(info.cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, info.pipeline);
323 vkCmdBindDescriptorSets(info.cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, info.pipeline_layout, 0,
324 NUM_DESCRIPTOR_SETS, info.desc_set.data(), 0, NULL);
325
326 const VkDeviceSize offsets[1] = {0};
327 vkCmdBindVertexBuffers(info.cmd, 0, 1, &info.vertex_buffer.buf, offsets);
328
329 init_viewports(info);
330 init_scissors(info);
331
332 vkCmdDraw(info.cmd, 0, 1, 0, 0);
333 vkCmdEndRenderPass(info.cmd);
334 }
335 res = vkEndCommandBuffer(info.cmd);
336 ASSERT_EQ(VK_SUCCESS, res);
337
338 const VkCommandBuffer cmd_bufs[] = {info.cmd};
339 VkPipelineStageFlags pipe_stage_flags = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
340 VkSubmitInfo submitInfo[1] = {};
341 submitInfo[0].pNext = NULL;
342 submitInfo[0].sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
343 submitInfo[0].waitSemaphoreCount = 1;
344 submitInfo[0].pWaitSemaphores = &imageAcquiredSemaphore;
345 submitInfo[0].pWaitDstStageMask = &pipe_stage_flags;
346 submitInfo[0].commandBufferCount = 1;
347 submitInfo[0].pCommandBuffers = cmd_bufs;
348 submitInfo[0].signalSemaphoreCount = 0;
349 submitInfo[0].pSignalSemaphores = NULL;
350
351 // Queue the command buffer for execution
352 res = vkQueueSubmit(info.graphics_queue, 1, submitInfo, drawFence);
353 ASSERT_EQ(VK_SUCCESS, res);
354
355 Present(info, drawFence);
356 }
357
358 // 100 separate secondary cmd buffers, each with 1 Draw
SecondaryCommandBufferBenchmark(sample_info & info,VkClearValue * clear_values,VkFence drawFence,VkSemaphore imageAcquiredSemaphore,int numBuffers)359 void SecondaryCommandBufferBenchmark(sample_info &info,
360 VkClearValue *clear_values,
361 VkFence drawFence,
362 VkSemaphore imageAcquiredSemaphore,
363 int numBuffers)
364 {
365 VkResult res;
366
367 // Record Secondary Command Buffer
368 VkCommandBufferInheritanceInfo inheritInfo = {};
369 inheritInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
370 inheritInfo.pNext = NULL;
371 inheritInfo.renderPass = info.render_pass;
372 inheritInfo.subpass = 0;
373 inheritInfo.framebuffer = info.framebuffers[info.current_buffer];
374 inheritInfo.occlusionQueryEnable = false;
375 inheritInfo.queryFlags = 0;
376 inheritInfo.pipelineStatistics = 0;
377
378 VkCommandBufferBeginInfo secondaryCommandBufferInfo = {};
379 secondaryCommandBufferInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
380 secondaryCommandBufferInfo.pNext = NULL;
381 secondaryCommandBufferInfo.flags = VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT |
382 VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT;
383 secondaryCommandBufferInfo.pInheritanceInfo = &inheritInfo;
384
385 for (int x = 0; x < numBuffers; x++)
386 {
387 vkBeginCommandBuffer(info.cmd2s[x], &secondaryCommandBufferInfo);
388 vkCmdBindPipeline(info.cmd2s[x], VK_PIPELINE_BIND_POINT_GRAPHICS, info.pipeline);
389 vkCmdBindDescriptorSets(info.cmd2s[x], VK_PIPELINE_BIND_POINT_GRAPHICS,
390 info.pipeline_layout, 0, NUM_DESCRIPTOR_SETS, info.desc_set.data(),
391 0, NULL);
392 const VkDeviceSize offsets[1] = {0};
393 vkCmdBindVertexBuffers(info.cmd2s[x], 0, 1, &info.vertex_buffer.buf, offsets);
394 init_viewports2_array(info, x);
395 init_scissors2_array(info, x);
396 vkCmdDraw(info.cmd2s[x], 0, 1, 0, 0);
397 vkEndCommandBuffer(info.cmd2s[x]);
398 }
399 // Record Secondary Command Buffer End
400
401 // Record Primary Command Buffer Begin
402 VkRenderPassBeginInfo rpBegin;
403 rpBegin.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
404 rpBegin.pNext = NULL;
405 rpBegin.renderPass = info.render_pass;
406 rpBegin.framebuffer = info.framebuffers[info.current_buffer];
407 rpBegin.renderArea.offset.x = 0;
408 rpBegin.renderArea.offset.y = 0;
409 rpBegin.renderArea.extent.width = info.width;
410 rpBegin.renderArea.extent.height = info.height;
411 rpBegin.clearValueCount = 2;
412 rpBegin.pClearValues = clear_values;
413
414 VkCommandBufferBeginInfo primaryCommandBufferInfo = {};
415 primaryCommandBufferInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
416 primaryCommandBufferInfo.pNext = NULL;
417 primaryCommandBufferInfo.flags = 0;
418 primaryCommandBufferInfo.pInheritanceInfo = NULL;
419
420 vkBeginCommandBuffer(info.cmd, &primaryCommandBufferInfo);
421 for (int x = 0; x < numBuffers; x++)
422 {
423 vkCmdBeginRenderPass(info.cmd, &rpBegin, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
424 vkCmdExecuteCommands(info.cmd, 1, &info.cmd2s[x]);
425 vkCmdEndRenderPass(info.cmd);
426 }
427 vkEndCommandBuffer(info.cmd);
428 // Record Primary Command Buffer End
429
430 const VkCommandBuffer cmd_bufs[] = {info.cmd};
431 VkPipelineStageFlags pipe_stage_flags = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
432 VkSubmitInfo submitInfo[1] = {};
433 submitInfo[0].pNext = NULL;
434 submitInfo[0].sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
435 submitInfo[0].waitSemaphoreCount = 1;
436 submitInfo[0].pWaitSemaphores = &imageAcquiredSemaphore;
437 submitInfo[0].pWaitDstStageMask = &pipe_stage_flags;
438 submitInfo[0].commandBufferCount = 1;
439 submitInfo[0].pCommandBuffers = cmd_bufs;
440 submitInfo[0].signalSemaphoreCount = 0;
441 submitInfo[0].pSignalSemaphores = NULL;
442
443 // Queue the command buffer for execution
444 res = vkQueueSubmit(info.graphics_queue, 1, submitInfo, drawFence);
445 ASSERT_EQ(VK_SUCCESS, res);
446
447 Present(info, drawFence);
448 }
449
450 // Details on the following functions that stress various cmd buffer reset methods.
451 // All of these functions wrap the SecondaryCommandBufferBenchmark() test above,
452 // adding additional overhead with various reset methods.
453 // -CommandPoolDestroyBenchmark: Reset command buffers by destroying and re-creating
454 // command buffer pool.
455 // -CommandPoolHardResetBenchmark: Reset the command pool w/ the RELEASE_RESOURCES
456 // bit set.
457 // -CommandPoolSoftResetBenchmark: Reset to command pool w/o the RELEASE_RESOURCES
458 // bit set.
459 // -CommandBufferExplicitHardResetBenchmark: Reset each individual command buffer
460 // w/ the RELEASE_RESOURCES bit set.
461 // -CommandBufferExplicitSoftResetBenchmark: Reset each individual command buffer
462 // w/o the RELEASE_RESOURCES bit set.
463 // -CommandBufferImplicitResetBenchmark: Reset each individual command buffer
464 // implicitly by calling "Begin" on previously used cmd buffer.
465
CommandPoolDestroyBenchmark(sample_info & info,VkClearValue * clear_values,VkFence drawFence,VkSemaphore imageAcquiredSemaphore,int numBuffers)466 void CommandPoolDestroyBenchmark(sample_info &info,
467 VkClearValue *clear_values,
468 VkFence drawFence,
469 VkSemaphore imageAcquiredSemaphore,
470 int numBuffers)
471 {
472 // Save setup cmd buffer data to be restored
473 auto saved_cmd_pool = info.cmd_pool;
474 auto saved_cb = info.cmd;
475 auto saved_cb2s = info.cmd2s;
476 // Now re-allocate & destroy cmd buffers to stress those calls
477 init_command_pool(info, 0);
478 init_command_buffer2_array(info, numBuffers);
479
480 SecondaryCommandBufferBenchmark(info, clear_values, drawFence, imageAcquiredSemaphore,
481 numBuffers);
482
483 destroy_command_pool(info);
484
485 // Restore original cmd buffer data for cleanup
486 info.cmd_pool = saved_cmd_pool;
487 info.cmd = saved_cb;
488 info.cmd2s = saved_cb2s;
489 }
490
CommandPoolHardResetBenchmark(sample_info & info,VkClearValue * clear_values,VkFence drawFence,VkSemaphore imageAcquiredSemaphore,int numBuffers)491 void CommandPoolHardResetBenchmark(sample_info &info,
492 VkClearValue *clear_values,
493 VkFence drawFence,
494 VkSemaphore imageAcquiredSemaphore,
495 int numBuffers)
496 {
497 SecondaryCommandBufferBenchmark(info, clear_values, drawFence, imageAcquiredSemaphore,
498 numBuffers);
499 reset_command_pool(info, VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT);
500 }
501
CommandPoolSoftResetBenchmark(sample_info & info,VkClearValue * clear_values,VkFence drawFence,VkSemaphore imageAcquiredSemaphore,int numBuffers)502 void CommandPoolSoftResetBenchmark(sample_info &info,
503 VkClearValue *clear_values,
504 VkFence drawFence,
505 VkSemaphore imageAcquiredSemaphore,
506 int numBuffers)
507 {
508 SecondaryCommandBufferBenchmark(info, clear_values, drawFence, imageAcquiredSemaphore,
509 numBuffers);
510 reset_command_pool(info, 0);
511 }
512
CommandBufferExplicitHardResetBenchmark(sample_info & info,VkClearValue * clear_values,VkFence drawFence,VkSemaphore imageAcquiredSemaphore,int numBuffers)513 void CommandBufferExplicitHardResetBenchmark(sample_info &info,
514 VkClearValue *clear_values,
515 VkFence drawFence,
516 VkSemaphore imageAcquiredSemaphore,
517 int numBuffers)
518 {
519 SecondaryCommandBufferBenchmark(info, clear_values, drawFence, imageAcquiredSemaphore,
520 numBuffers);
521 // Explicitly resetting cmd buffers
522 reset_command_buffer2_array(info, VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT);
523 }
524
CommandBufferExplicitSoftResetBenchmark(sample_info & info,VkClearValue * clear_values,VkFence drawFence,VkSemaphore imageAcquiredSemaphore,int numBuffers)525 void CommandBufferExplicitSoftResetBenchmark(sample_info &info,
526 VkClearValue *clear_values,
527 VkFence drawFence,
528 VkSemaphore imageAcquiredSemaphore,
529 int numBuffers)
530 {
531 SecondaryCommandBufferBenchmark(info, clear_values, drawFence, imageAcquiredSemaphore,
532 numBuffers);
533 // Explicitly resetting cmd buffers w/ soft reset (don't release resources)
534 reset_command_buffer2_array(info, 0);
535 }
536
CommandBufferImplicitResetBenchmark(sample_info & info,VkClearValue * clear_values,VkFence drawFence,VkSemaphore imageAcquiredSemaphore,int numBuffers)537 void CommandBufferImplicitResetBenchmark(sample_info &info,
538 VkClearValue *clear_values,
539 VkFence drawFence,
540 VkSemaphore imageAcquiredSemaphore,
541 int numBuffers)
542 {
543 // Repeated call SCBBenchmark & BeginCmdBuffer calls will implicitly reset each cmd buffer
544 SecondaryCommandBufferBenchmark(info, clear_values, drawFence, imageAcquiredSemaphore,
545 numBuffers);
546 }
547
PrimaryCBHundredIndividualParams()548 CommandBufferTestParams PrimaryCBHundredIndividualParams()
549 {
550 CommandBufferTestParams params;
551 params.CBImplementation = PrimaryCommandBufferBenchmarkHundredIndividual;
552 params.story = "_PrimaryCB_Submit_100_With_1_Draw";
553 return params;
554 }
555
PrimaryCBOneWithOneHundredParams()556 CommandBufferTestParams PrimaryCBOneWithOneHundredParams()
557 {
558 CommandBufferTestParams params;
559 params.CBImplementation = PrimaryCommandBufferBenchmarkOneWithOneHundred;
560 params.story = "_PrimaryCB_Submit_1_With_100_Draw";
561 return params;
562 }
563
SecondaryCBParams()564 CommandBufferTestParams SecondaryCBParams()
565 {
566 CommandBufferTestParams params;
567 params.CBImplementation = SecondaryCommandBufferBenchmark;
568 params.story = "_SecondaryCB_Submit_1_With_100_Draw_In_Individual_Secondary";
569 return params;
570 }
571
CommandPoolDestroyParams()572 CommandBufferTestParams CommandPoolDestroyParams()
573 {
574 CommandBufferTestParams params;
575 params.CBImplementation = CommandPoolDestroyBenchmark;
576 params.story = "_Reset_CBs_With_Destroy_Command_Pool";
577 return params;
578 }
579
CommandPoolHardResetParams()580 CommandBufferTestParams CommandPoolHardResetParams()
581 {
582 CommandBufferTestParams params;
583 params.CBImplementation = CommandPoolHardResetBenchmark;
584 params.story = "_Reset_CBs_With_Hard_Reset_Command_Pool";
585 return params;
586 }
587
CommandPoolSoftResetParams()588 CommandBufferTestParams CommandPoolSoftResetParams()
589 {
590 CommandBufferTestParams params;
591 params.CBImplementation = CommandPoolSoftResetBenchmark;
592 params.story = "_Reset_CBs_With_Soft_Reset_Command_Pool";
593 return params;
594 }
595
CommandBufferExplicitHardResetParams()596 CommandBufferTestParams CommandBufferExplicitHardResetParams()
597 {
598 CommandBufferTestParams params;
599 params.CBImplementation = CommandBufferExplicitHardResetBenchmark;
600 params.story = "_Reset_CBs_With_Explicit_Hard_Reset_Command_Buffers";
601 return params;
602 }
603
CommandBufferExplicitSoftResetParams()604 CommandBufferTestParams CommandBufferExplicitSoftResetParams()
605 {
606 CommandBufferTestParams params;
607 params.CBImplementation = CommandBufferExplicitSoftResetBenchmark;
608 params.story = "_Reset_CBs_With_Explicit_Soft_Reset_Command_Buffers";
609 return params;
610 }
611
CommandBufferImplicitResetParams()612 CommandBufferTestParams CommandBufferImplicitResetParams()
613 {
614 CommandBufferTestParams params;
615 params.CBImplementation = CommandBufferImplicitResetBenchmark;
616 params.story = "_Reset_CBs_With_Implicit_Reset_Command_Buffers";
617 return params;
618 }
619
TEST_P(VulkanCommandBufferPerfTest,Run)620 TEST_P(VulkanCommandBufferPerfTest, Run)
621 {
622 run();
623 }
624
625 INSTANTIATE_TEST_SUITE_P(,
626 VulkanCommandBufferPerfTest,
627 ::testing::Values(PrimaryCBHundredIndividualParams(),
628 PrimaryCBOneWithOneHundredParams(),
629 SecondaryCBParams(),
630 CommandPoolDestroyParams(),
631 CommandPoolHardResetParams(),
632 CommandPoolSoftResetParams(),
633 CommandBufferExplicitHardResetParams(),
634 CommandBufferExplicitSoftResetParams(),
635 CommandBufferImplicitResetParams()));
636