xref: /aosp_15_r20/external/angle/src/tests/perf_tests/VulkanCommandBufferPerf.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
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     ANGLEPerfTest::SetUp();
104 
105     init_global_layer_properties(mInfo);
106     init_instance_extension_names(mInfo);
107     init_device_extension_names(mInfo);
108     init_instance(mInfo, mSampleTitle.c_str());
109     init_enumerate_device(mInfo);
110     init_window_size(mInfo, 500, 500);
111     init_connection(mInfo);
112     init_window(mInfo);
113     init_swapchain_extension(mInfo);
114     init_device(mInfo);
115 
116     init_command_pool(mInfo, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT);
117     init_command_buffer(mInfo);                   // Primary command buffer to hold secondaries
118     init_command_buffer_array(mInfo, mBuffers);   // Array of primary command buffers
119     init_command_buffer2_array(mInfo, mBuffers);  // Array containing all secondary buffers
120     init_device_queue(mInfo);
121     init_swap_chain(mInfo);
122     init_depth_buffer(mInfo);
123     init_uniform_buffer(mInfo);
124     init_descriptor_and_pipeline_layouts(mInfo, false);
125     init_renderpass(mInfo, mDepthPresent);
126     init_shaders(mInfo, kVertShaderText, kFragShaderText);
127     init_framebuffers(mInfo, mDepthPresent);
128     init_vertex_buffer(mInfo, g_vb_solid_face_colors_Data, sizeof(g_vb_solid_face_colors_Data),
129                        sizeof(g_vb_solid_face_colors_Data[0]), false);
130     init_descriptor_pool(mInfo, false);
131     init_descriptor_set(mInfo);
132     init_pipeline_cache(mInfo);
133     init_pipeline(mInfo, mDepthPresent);
134 
135     mClearValues[0].color.float32[0]     = 0.2f;
136     mClearValues[0].color.float32[1]     = 0.2f;
137     mClearValues[0].color.float32[2]     = 0.2f;
138     mClearValues[0].color.float32[3]     = 0.2f;
139     mClearValues[1].depthStencil.depth   = 1.0f;
140     mClearValues[1].depthStencil.stencil = 0;
141 
142     VkSemaphoreCreateInfo imageAcquiredSemaphoreCreateInfo;
143     imageAcquiredSemaphoreCreateInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
144     imageAcquiredSemaphoreCreateInfo.pNext = NULL;
145     imageAcquiredSemaphoreCreateInfo.flags = 0;
146     res = vkCreateSemaphore(mInfo.device, &imageAcquiredSemaphoreCreateInfo, NULL,
147                             &mImageAcquiredSemaphore);
148     ASSERT_EQ(VK_SUCCESS, res);
149 
150     VkFenceCreateInfo fenceInfo;
151     fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
152     fenceInfo.pNext = NULL;
153     fenceInfo.flags = 0;
154     res             = vkCreateFence(mInfo.device, &fenceInfo, NULL, &mDrawFence);
155     ASSERT_EQ(VK_SUCCESS, res);
156 }
157 
step()158 void VulkanCommandBufferPerfTest::step()
159 {
160     for (int x = 0; x < mFrames; x++)
161     {
162         mInfo.current_buffer = x % mInfo.swapchainImageCount;
163 
164         // Get the index of the next available swapchain image:
165         res = vkAcquireNextImageKHR(mInfo.device, mInfo.swap_chain, UINT64_MAX,
166                                     mImageAcquiredSemaphore, VK_NULL_HANDLE, &mInfo.current_buffer);
167         // Deal with the VK_SUBOPTIMAL_KHR and VK_ERROR_OUT_OF_DATE_KHR
168         // return codes
169         ASSERT_EQ(VK_SUCCESS, res);
170         mCBImplementation(mInfo, mClearValues, mDrawFence, mImageAcquiredSemaphore, mBuffers);
171     }
172 }
173 
TearDown()174 void VulkanCommandBufferPerfTest::TearDown()
175 {
176     vkDestroySemaphore(mInfo.device, mImageAcquiredSemaphore, NULL);
177     vkDestroyFence(mInfo.device, mDrawFence, NULL);
178     destroy_pipeline(mInfo);
179     destroy_pipeline_cache(mInfo);
180     destroy_descriptor_pool(mInfo);
181     destroy_vertex_buffer(mInfo);
182     destroy_framebuffers(mInfo);
183     destroy_shaders(mInfo);
184     destroy_renderpass(mInfo);
185     destroy_descriptor_and_pipeline_layouts(mInfo);
186     destroy_uniform_buffer(mInfo);
187     destroy_depth_buffer(mInfo);
188     destroy_swap_chain(mInfo);
189     destroy_command_buffer2_array(mInfo, mBuffers);
190     destroy_command_buffer_array(mInfo, mBuffers);
191     destroy_command_buffer(mInfo);
192     destroy_command_pool(mInfo);
193     destroy_device(mInfo);
194     destroy_window(mInfo);
195     destroy_instance(mInfo);
196     ANGLEPerfTest::TearDown();
197 }
198 
199 // Common code to present image used by all tests
Present(sample_info & info,VkFence drawFence)200 void Present(sample_info &info, VkFence drawFence)
201 {
202     // Now present the image in the window
203 
204     VkPresentInfoKHR present;
205     present.sType              = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
206     present.pNext              = NULL;
207     present.swapchainCount     = 1;
208     present.pSwapchains        = &info.swap_chain;
209     present.pImageIndices      = &info.current_buffer;
210     present.pWaitSemaphores    = NULL;
211     present.waitSemaphoreCount = 0;
212     present.pResults           = NULL;
213 
214     // Make sure command buffer is finished before presenting
215     VkResult res;
216     do
217     {
218         res = vkWaitForFences(info.device, 1, &drawFence, VK_TRUE, FENCE_TIMEOUT);
219     } while (res == VK_TIMEOUT);
220     vkResetFences(info.device, 1, &drawFence);
221 
222     ASSERT_EQ(VK_SUCCESS, res);
223     res = vkQueuePresentKHR(info.present_queue, &present);
224     ASSERT_EQ(VK_SUCCESS, res);
225 }
226 
227 // 100 separate primary cmd buffers, each with 1 Draw
PrimaryCommandBufferBenchmarkHundredIndividual(sample_info & info,VkClearValue * clear_values,VkFence drawFence,VkSemaphore imageAcquiredSemaphore,int numBuffers)228 void PrimaryCommandBufferBenchmarkHundredIndividual(sample_info &info,
229                                                     VkClearValue *clear_values,
230                                                     VkFence drawFence,
231                                                     VkSemaphore imageAcquiredSemaphore,
232                                                     int numBuffers)
233 {
234     VkResult res;
235 
236     VkRenderPassBeginInfo rpBegin;
237     rpBegin.sType                    = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
238     rpBegin.pNext                    = NULL;
239     rpBegin.renderPass               = info.render_pass;
240     rpBegin.framebuffer              = info.framebuffers[info.current_buffer];
241     rpBegin.renderArea.offset.x      = 0;
242     rpBegin.renderArea.offset.y      = 0;
243     rpBegin.renderArea.extent.width  = info.width;
244     rpBegin.renderArea.extent.height = info.height;
245     rpBegin.clearValueCount          = 2;
246     rpBegin.pClearValues             = clear_values;
247 
248     VkCommandBufferBeginInfo cmdBufferInfo = {};
249     cmdBufferInfo.sType                    = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
250     cmdBufferInfo.pNext                    = NULL;
251     cmdBufferInfo.flags                    = 0;
252     cmdBufferInfo.pInheritanceInfo         = NULL;
253 
254     for (int x = 0; x < numBuffers; x++)
255     {
256         vkBeginCommandBuffer(info.cmds[x], &cmdBufferInfo);
257         vkCmdBeginRenderPass(info.cmds[x], &rpBegin, VK_SUBPASS_CONTENTS_INLINE);
258         vkCmdBindPipeline(info.cmds[x], VK_PIPELINE_BIND_POINT_GRAPHICS, info.pipeline);
259         vkCmdBindDescriptorSets(info.cmds[x], VK_PIPELINE_BIND_POINT_GRAPHICS, info.pipeline_layout,
260                                 0, NUM_DESCRIPTOR_SETS, info.desc_set.data(), 0, NULL);
261 
262         const VkDeviceSize offsets[1] = {0};
263         vkCmdBindVertexBuffers(info.cmds[x], 0, 1, &info.vertex_buffer.buf, offsets);
264 
265         init_viewports_array(info, x);
266         init_scissors_array(info, x);
267 
268         vkCmdDraw(info.cmds[x], 0, 1, 0, 0);
269         vkCmdEndRenderPass(info.cmds[x]);
270         res = vkEndCommandBuffer(info.cmds[x]);
271         ASSERT_EQ(VK_SUCCESS, res);
272     }
273 
274     VkPipelineStageFlags pipe_stage_flags = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
275     VkSubmitInfo submitInfo[1]            = {};
276     submitInfo[0].pNext                   = NULL;
277     submitInfo[0].sType                   = VK_STRUCTURE_TYPE_SUBMIT_INFO;
278     submitInfo[0].waitSemaphoreCount      = 1;
279     submitInfo[0].pWaitSemaphores         = &imageAcquiredSemaphore;
280     submitInfo[0].pWaitDstStageMask       = &pipe_stage_flags;
281     submitInfo[0].commandBufferCount      = numBuffers;
282     submitInfo[0].pCommandBuffers         = info.cmds.data();
283     submitInfo[0].signalSemaphoreCount    = 0;
284     submitInfo[0].pSignalSemaphores       = NULL;
285 
286     // Queue the command buffer for execution
287     res = vkQueueSubmit(info.graphics_queue, 1, submitInfo, drawFence);
288     ASSERT_EQ(VK_SUCCESS, res);
289 
290     Present(info, drawFence);
291 }
292 
293 // 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)294 void PrimaryCommandBufferBenchmarkOneWithOneHundred(sample_info &info,
295                                                     VkClearValue *clear_values,
296                                                     VkFence drawFence,
297                                                     VkSemaphore imageAcquiredSemaphore,
298                                                     int numBuffers)
299 {
300     VkResult res;
301 
302     VkRenderPassBeginInfo rpBegin;
303     rpBegin.sType                    = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
304     rpBegin.pNext                    = NULL;
305     rpBegin.renderPass               = info.render_pass;
306     rpBegin.framebuffer              = info.framebuffers[info.current_buffer];
307     rpBegin.renderArea.offset.x      = 0;
308     rpBegin.renderArea.offset.y      = 0;
309     rpBegin.renderArea.extent.width  = info.width;
310     rpBegin.renderArea.extent.height = info.height;
311     rpBegin.clearValueCount          = 2;
312     rpBegin.pClearValues             = clear_values;
313 
314     VkCommandBufferBeginInfo cmdBufferInfo = {};
315     cmdBufferInfo.sType                    = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
316     cmdBufferInfo.pNext                    = NULL;
317     cmdBufferInfo.flags                    = 0;
318     cmdBufferInfo.pInheritanceInfo         = NULL;
319 
320     vkBeginCommandBuffer(info.cmd, &cmdBufferInfo);
321     for (int x = 0; x < numBuffers; x++)
322     {
323         vkCmdBeginRenderPass(info.cmd, &rpBegin, VK_SUBPASS_CONTENTS_INLINE);
324         vkCmdBindPipeline(info.cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, info.pipeline);
325         vkCmdBindDescriptorSets(info.cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, info.pipeline_layout, 0,
326                                 NUM_DESCRIPTOR_SETS, info.desc_set.data(), 0, NULL);
327 
328         const VkDeviceSize offsets[1] = {0};
329         vkCmdBindVertexBuffers(info.cmd, 0, 1, &info.vertex_buffer.buf, offsets);
330 
331         init_viewports(info);
332         init_scissors(info);
333 
334         vkCmdDraw(info.cmd, 0, 1, 0, 0);
335         vkCmdEndRenderPass(info.cmd);
336     }
337     res = vkEndCommandBuffer(info.cmd);
338     ASSERT_EQ(VK_SUCCESS, res);
339 
340     const VkCommandBuffer cmd_bufs[]      = {info.cmd};
341     VkPipelineStageFlags pipe_stage_flags = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
342     VkSubmitInfo submitInfo[1]            = {};
343     submitInfo[0].pNext                   = NULL;
344     submitInfo[0].sType                   = VK_STRUCTURE_TYPE_SUBMIT_INFO;
345     submitInfo[0].waitSemaphoreCount      = 1;
346     submitInfo[0].pWaitSemaphores         = &imageAcquiredSemaphore;
347     submitInfo[0].pWaitDstStageMask       = &pipe_stage_flags;
348     submitInfo[0].commandBufferCount      = 1;
349     submitInfo[0].pCommandBuffers         = cmd_bufs;
350     submitInfo[0].signalSemaphoreCount    = 0;
351     submitInfo[0].pSignalSemaphores       = NULL;
352 
353     // Queue the command buffer for execution
354     res = vkQueueSubmit(info.graphics_queue, 1, submitInfo, drawFence);
355     ASSERT_EQ(VK_SUCCESS, res);
356 
357     Present(info, drawFence);
358 }
359 
360 // 100 separate secondary cmd buffers, each with 1 Draw
SecondaryCommandBufferBenchmark(sample_info & info,VkClearValue * clear_values,VkFence drawFence,VkSemaphore imageAcquiredSemaphore,int numBuffers)361 void SecondaryCommandBufferBenchmark(sample_info &info,
362                                      VkClearValue *clear_values,
363                                      VkFence drawFence,
364                                      VkSemaphore imageAcquiredSemaphore,
365                                      int numBuffers)
366 {
367     VkResult res;
368 
369     // Record Secondary Command Buffer
370     VkCommandBufferInheritanceInfo inheritInfo = {};
371     inheritInfo.sType                          = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
372     inheritInfo.pNext                          = NULL;
373     inheritInfo.renderPass                     = info.render_pass;
374     inheritInfo.subpass                        = 0;
375     inheritInfo.framebuffer                    = info.framebuffers[info.current_buffer];
376     inheritInfo.occlusionQueryEnable           = false;
377     inheritInfo.queryFlags                     = 0;
378     inheritInfo.pipelineStatistics             = 0;
379 
380     VkCommandBufferBeginInfo secondaryCommandBufferInfo = {};
381     secondaryCommandBufferInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
382     secondaryCommandBufferInfo.pNext = NULL;
383     secondaryCommandBufferInfo.flags = VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT |
384                                        VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT;
385     secondaryCommandBufferInfo.pInheritanceInfo = &inheritInfo;
386 
387     for (int x = 0; x < numBuffers; x++)
388     {
389         vkBeginCommandBuffer(info.cmd2s[x], &secondaryCommandBufferInfo);
390         vkCmdBindPipeline(info.cmd2s[x], VK_PIPELINE_BIND_POINT_GRAPHICS, info.pipeline);
391         vkCmdBindDescriptorSets(info.cmd2s[x], VK_PIPELINE_BIND_POINT_GRAPHICS,
392                                 info.pipeline_layout, 0, NUM_DESCRIPTOR_SETS, info.desc_set.data(),
393                                 0, NULL);
394         const VkDeviceSize offsets[1] = {0};
395         vkCmdBindVertexBuffers(info.cmd2s[x], 0, 1, &info.vertex_buffer.buf, offsets);
396         init_viewports2_array(info, x);
397         init_scissors2_array(info, x);
398         vkCmdDraw(info.cmd2s[x], 0, 1, 0, 0);
399         vkEndCommandBuffer(info.cmd2s[x]);
400     }
401     // Record Secondary Command Buffer End
402 
403     // Record Primary Command Buffer Begin
404     VkRenderPassBeginInfo rpBegin;
405     rpBegin.sType                    = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
406     rpBegin.pNext                    = NULL;
407     rpBegin.renderPass               = info.render_pass;
408     rpBegin.framebuffer              = info.framebuffers[info.current_buffer];
409     rpBegin.renderArea.offset.x      = 0;
410     rpBegin.renderArea.offset.y      = 0;
411     rpBegin.renderArea.extent.width  = info.width;
412     rpBegin.renderArea.extent.height = info.height;
413     rpBegin.clearValueCount          = 2;
414     rpBegin.pClearValues             = clear_values;
415 
416     VkCommandBufferBeginInfo primaryCommandBufferInfo = {};
417     primaryCommandBufferInfo.sType                    = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
418     primaryCommandBufferInfo.pNext                    = NULL;
419     primaryCommandBufferInfo.flags                    = 0;
420     primaryCommandBufferInfo.pInheritanceInfo         = NULL;
421 
422     vkBeginCommandBuffer(info.cmd, &primaryCommandBufferInfo);
423     for (int x = 0; x < numBuffers; x++)
424     {
425         vkCmdBeginRenderPass(info.cmd, &rpBegin, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
426         vkCmdExecuteCommands(info.cmd, 1, &info.cmd2s[x]);
427         vkCmdEndRenderPass(info.cmd);
428     }
429     vkEndCommandBuffer(info.cmd);
430     // Record Primary Command Buffer End
431 
432     const VkCommandBuffer cmd_bufs[]      = {info.cmd};
433     VkPipelineStageFlags pipe_stage_flags = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
434     VkSubmitInfo submitInfo[1]            = {};
435     submitInfo[0].pNext                   = NULL;
436     submitInfo[0].sType                   = VK_STRUCTURE_TYPE_SUBMIT_INFO;
437     submitInfo[0].waitSemaphoreCount      = 1;
438     submitInfo[0].pWaitSemaphores         = &imageAcquiredSemaphore;
439     submitInfo[0].pWaitDstStageMask       = &pipe_stage_flags;
440     submitInfo[0].commandBufferCount      = 1;
441     submitInfo[0].pCommandBuffers         = cmd_bufs;
442     submitInfo[0].signalSemaphoreCount    = 0;
443     submitInfo[0].pSignalSemaphores       = NULL;
444 
445     // Queue the command buffer for execution
446     res = vkQueueSubmit(info.graphics_queue, 1, submitInfo, drawFence);
447     ASSERT_EQ(VK_SUCCESS, res);
448 
449     Present(info, drawFence);
450 }
451 
452 // Details on the following functions that stress various cmd buffer reset methods.
453 // All of these functions wrap the SecondaryCommandBufferBenchmark() test above,
454 // adding additional overhead with various reset methods.
455 // -CommandPoolDestroyBenchmark: Reset command buffers by destroying and re-creating
456 //   command buffer pool.
457 // -CommandPoolHardResetBenchmark: Reset the command pool w/ the RELEASE_RESOURCES
458 //   bit set.
459 // -CommandPoolSoftResetBenchmark: Reset to command pool w/o the RELEASE_RESOURCES
460 //   bit set.
461 // -CommandBufferExplicitHardResetBenchmark: Reset each individual command buffer
462 //   w/ the RELEASE_RESOURCES bit set.
463 // -CommandBufferExplicitSoftResetBenchmark: Reset each individual command buffer
464 //   w/o the RELEASE_RESOURCES bit set.
465 // -CommandBufferImplicitResetBenchmark: Reset each individual command buffer
466 //   implicitly by calling "Begin" on previously used cmd buffer.
467 
CommandPoolDestroyBenchmark(sample_info & info,VkClearValue * clear_values,VkFence drawFence,VkSemaphore imageAcquiredSemaphore,int numBuffers)468 void CommandPoolDestroyBenchmark(sample_info &info,
469                                  VkClearValue *clear_values,
470                                  VkFence drawFence,
471                                  VkSemaphore imageAcquiredSemaphore,
472                                  int numBuffers)
473 {
474     // Save setup cmd buffer data to be restored
475     auto saved_cmd_pool = info.cmd_pool;
476     auto saved_cb       = info.cmd;
477     auto saved_cb2s     = info.cmd2s;
478     // Now re-allocate & destroy cmd buffers to stress those calls
479     init_command_pool(info, 0);
480     init_command_buffer2_array(info, numBuffers);
481 
482     SecondaryCommandBufferBenchmark(info, clear_values, drawFence, imageAcquiredSemaphore,
483                                     numBuffers);
484 
485     destroy_command_pool(info);
486 
487     // Restore original cmd buffer data for cleanup
488     info.cmd_pool = saved_cmd_pool;
489     info.cmd      = saved_cb;
490     info.cmd2s    = saved_cb2s;
491 }
492 
CommandPoolHardResetBenchmark(sample_info & info,VkClearValue * clear_values,VkFence drawFence,VkSemaphore imageAcquiredSemaphore,int numBuffers)493 void CommandPoolHardResetBenchmark(sample_info &info,
494                                    VkClearValue *clear_values,
495                                    VkFence drawFence,
496                                    VkSemaphore imageAcquiredSemaphore,
497                                    int numBuffers)
498 {
499     SecondaryCommandBufferBenchmark(info, clear_values, drawFence, imageAcquiredSemaphore,
500                                     numBuffers);
501     reset_command_pool(info, VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT);
502 }
503 
CommandPoolSoftResetBenchmark(sample_info & info,VkClearValue * clear_values,VkFence drawFence,VkSemaphore imageAcquiredSemaphore,int numBuffers)504 void CommandPoolSoftResetBenchmark(sample_info &info,
505                                    VkClearValue *clear_values,
506                                    VkFence drawFence,
507                                    VkSemaphore imageAcquiredSemaphore,
508                                    int numBuffers)
509 {
510     SecondaryCommandBufferBenchmark(info, clear_values, drawFence, imageAcquiredSemaphore,
511                                     numBuffers);
512     reset_command_pool(info, 0);
513 }
514 
CommandBufferExplicitHardResetBenchmark(sample_info & info,VkClearValue * clear_values,VkFence drawFence,VkSemaphore imageAcquiredSemaphore,int numBuffers)515 void CommandBufferExplicitHardResetBenchmark(sample_info &info,
516                                              VkClearValue *clear_values,
517                                              VkFence drawFence,
518                                              VkSemaphore imageAcquiredSemaphore,
519                                              int numBuffers)
520 {
521     SecondaryCommandBufferBenchmark(info, clear_values, drawFence, imageAcquiredSemaphore,
522                                     numBuffers);
523     // Explicitly resetting cmd buffers
524     reset_command_buffer2_array(info, VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT);
525 }
526 
CommandBufferExplicitSoftResetBenchmark(sample_info & info,VkClearValue * clear_values,VkFence drawFence,VkSemaphore imageAcquiredSemaphore,int numBuffers)527 void CommandBufferExplicitSoftResetBenchmark(sample_info &info,
528                                              VkClearValue *clear_values,
529                                              VkFence drawFence,
530                                              VkSemaphore imageAcquiredSemaphore,
531                                              int numBuffers)
532 {
533     SecondaryCommandBufferBenchmark(info, clear_values, drawFence, imageAcquiredSemaphore,
534                                     numBuffers);
535     // Explicitly resetting cmd buffers w/ soft reset (don't release resources)
536     reset_command_buffer2_array(info, 0);
537 }
538 
CommandBufferImplicitResetBenchmark(sample_info & info,VkClearValue * clear_values,VkFence drawFence,VkSemaphore imageAcquiredSemaphore,int numBuffers)539 void CommandBufferImplicitResetBenchmark(sample_info &info,
540                                          VkClearValue *clear_values,
541                                          VkFence drawFence,
542                                          VkSemaphore imageAcquiredSemaphore,
543                                          int numBuffers)
544 {
545     // Repeated call SCBBenchmark & BeginCmdBuffer calls will implicitly reset each cmd buffer
546     SecondaryCommandBufferBenchmark(info, clear_values, drawFence, imageAcquiredSemaphore,
547                                     numBuffers);
548 }
549 
PrimaryCBHundredIndividualParams()550 CommandBufferTestParams PrimaryCBHundredIndividualParams()
551 {
552     CommandBufferTestParams params;
553     params.CBImplementation = PrimaryCommandBufferBenchmarkHundredIndividual;
554     params.story            = "_PrimaryCB_Submit_100_With_1_Draw";
555     return params;
556 }
557 
PrimaryCBOneWithOneHundredParams()558 CommandBufferTestParams PrimaryCBOneWithOneHundredParams()
559 {
560     CommandBufferTestParams params;
561     params.CBImplementation = PrimaryCommandBufferBenchmarkOneWithOneHundred;
562     params.story            = "_PrimaryCB_Submit_1_With_100_Draw";
563     return params;
564 }
565 
SecondaryCBParams()566 CommandBufferTestParams SecondaryCBParams()
567 {
568     CommandBufferTestParams params;
569     params.CBImplementation = SecondaryCommandBufferBenchmark;
570     params.story            = "_SecondaryCB_Submit_1_With_100_Draw_In_Individual_Secondary";
571     return params;
572 }
573 
CommandPoolDestroyParams()574 CommandBufferTestParams CommandPoolDestroyParams()
575 {
576     CommandBufferTestParams params;
577     params.CBImplementation = CommandPoolDestroyBenchmark;
578     params.story            = "_Reset_CBs_With_Destroy_Command_Pool";
579     return params;
580 }
581 
CommandPoolHardResetParams()582 CommandBufferTestParams CommandPoolHardResetParams()
583 {
584     CommandBufferTestParams params;
585     params.CBImplementation = CommandPoolHardResetBenchmark;
586     params.story            = "_Reset_CBs_With_Hard_Reset_Command_Pool";
587     return params;
588 }
589 
CommandPoolSoftResetParams()590 CommandBufferTestParams CommandPoolSoftResetParams()
591 {
592     CommandBufferTestParams params;
593     params.CBImplementation = CommandPoolSoftResetBenchmark;
594     params.story            = "_Reset_CBs_With_Soft_Reset_Command_Pool";
595     return params;
596 }
597 
CommandBufferExplicitHardResetParams()598 CommandBufferTestParams CommandBufferExplicitHardResetParams()
599 {
600     CommandBufferTestParams params;
601     params.CBImplementation = CommandBufferExplicitHardResetBenchmark;
602     params.story            = "_Reset_CBs_With_Explicit_Hard_Reset_Command_Buffers";
603     return params;
604 }
605 
CommandBufferExplicitSoftResetParams()606 CommandBufferTestParams CommandBufferExplicitSoftResetParams()
607 {
608     CommandBufferTestParams params;
609     params.CBImplementation = CommandBufferExplicitSoftResetBenchmark;
610     params.story            = "_Reset_CBs_With_Explicit_Soft_Reset_Command_Buffers";
611     return params;
612 }
613 
CommandBufferImplicitResetParams()614 CommandBufferTestParams CommandBufferImplicitResetParams()
615 {
616     CommandBufferTestParams params;
617     params.CBImplementation = CommandBufferImplicitResetBenchmark;
618     params.story            = "_Reset_CBs_With_Implicit_Reset_Command_Buffers";
619     return params;
620 }
621 
TEST_P(VulkanCommandBufferPerfTest,Run)622 TEST_P(VulkanCommandBufferPerfTest, Run)
623 {
624     run();
625 }
626 
627 INSTANTIATE_TEST_SUITE_P(,
628                          VulkanCommandBufferPerfTest,
629                          ::testing::Values(PrimaryCBHundredIndividualParams(),
630                                            PrimaryCBOneWithOneHundredParams(),
631                                            SecondaryCBParams(),
632                                            CommandPoolDestroyParams(),
633                                            CommandPoolHardResetParams(),
634                                            CommandPoolSoftResetParams(),
635                                            CommandBufferExplicitHardResetParams(),
636                                            CommandBufferExplicitSoftResetParams(),
637                                            CommandBufferImplicitResetParams()));
638