• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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