// Copyright 2018 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// VulkanCommandBufferPerf:
//   Performance benchmark for Vulkan Primary/Secondary Command Buffer implementations.
//  Can run just these tests by adding "--gtest_filter=VulkanCommandBufferPerfTest*"
//   option to angle_white_box_perftests.
//  When running on Android with run_angle_white_box_perftests, use "-v" option.
//

#include "ANGLEPerfTest.h"
#include "common/platform.h"
#include "common/unsafe_buffers.h"
#include "test_utils/third_party/vulkan_command_buffer_utils.h"

#if defined(ANDROID)
#    define NUM_CMD_BUFFERS 1000
// Android devices tend to be slower so only do 10 frames to avoid timeout
#    define NUM_FRAMES 10
#else
#    define NUM_CMD_BUFFERS 1000
#    define NUM_FRAMES 100
#endif

// These are minimal shaders used to submit trivial draw commands to command
//  buffers so that we can create large batches of cmd buffers with consistent
//  draw patterns but size/type of cmd buffers can be varied to test cmd buffer
//  differences across devices.
constexpr char kVertShaderText[] = R"(
#version 400
#extension GL_ARB_separate_shader_objects : enable
#extension GL_ARB_shading_language_420pack : enable
layout (std140, binding = 0) uniform bufferVals {
    mat4 mvp;
} myBufferVals;
layout (location = 0) in vec4 pos;
layout (location = 1) in vec4 inColor;
layout (location = 0) out vec4 outColor;
void main() {
   outColor = inColor;
   gl_Position = myBufferVals.mvp * pos;
})";

constexpr char kFragShaderText[] = R"(
#version 400
#extension GL_ARB_separate_shader_objects : enable
#extension GL_ARB_shading_language_420pack : enable
layout (location = 0) in vec4 color;
layout (location = 0) out vec4 outColor;
void main() {
   outColor = color;
})";

using CommandBufferImpl = void (*)(sample_info &info,
                                   VkClearValue *clear_values,
                                   VkFence drawFence,
                                   VkSemaphore imageAcquiredSemaphore,
                                   int numBuffers);

struct CommandBufferTestParams
{
    CommandBufferImpl CBImplementation;
    std::string story;
    int frames  = NUM_FRAMES;
    int buffers = NUM_CMD_BUFFERS;
};

class VulkanCommandBufferPerfTest : public ANGLEPerfTest,
                                    public ::testing::WithParamInterface<CommandBufferTestParams>
{
  public:
    VulkanCommandBufferPerfTest();

    void SetUp() override;
    void TearDown() override;
    void step() override;

  private:
    VkClearValue mClearValues[2]        = {};
    VkSemaphore mImageAcquiredSemaphore = VK_NULL_HANDLE;
    VkFence mDrawFence                  = VK_NULL_HANDLE;

    VkResult res             = VK_NOT_READY;
    const bool mDepthPresent = true;
    struct sample_info mInfo = {};
    std::string mSampleTitle;
    CommandBufferImpl mCBImplementation = nullptr;
    int mFrames                         = 0;
    int mBuffers                        = 0;
};

VulkanCommandBufferPerfTest::VulkanCommandBufferPerfTest()
    : ANGLEPerfTest("VulkanCommandBufferPerfTest", "", GetParam().story, GetParam().frames)
{
    mInfo             = {};
    mSampleTitle      = "Draw Textured Cube";
    mCBImplementation = GetParam().CBImplementation;
    mFrames           = GetParam().frames;
    mBuffers          = GetParam().buffers;
}

void VulkanCommandBufferPerfTest::SetUp()
{
    ANGLEPerfTest::SetUp();

    init_global_layer_properties(mInfo);
    init_instance_extension_names(mInfo);
    init_device_extension_names(mInfo);
    init_instance(mInfo, mSampleTitle.c_str());
    init_enumerate_device(mInfo);
    init_window_size(mInfo, 500, 500);
    init_connection(mInfo);
    init_window(mInfo);
    init_swapchain_extension(mInfo);
    init_device(mInfo);

    init_command_pool(mInfo, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT);
    init_command_buffer(mInfo);                   // Primary command buffer to hold secondaries
    init_command_buffer_array(mInfo, mBuffers);   // Array of primary command buffers
    init_command_buffer2_array(mInfo, mBuffers);  // Array containing all secondary buffers
    init_device_queue(mInfo);
    init_swap_chain(mInfo);
    init_depth_buffer(mInfo);
    init_uniform_buffer(mInfo);
    init_descriptor_and_pipeline_layouts(mInfo, false);
    init_renderpass(mInfo, mDepthPresent);
    init_shaders(mInfo, kVertShaderText, kFragShaderText);
    init_framebuffers(mInfo, mDepthPresent);
    init_vertex_buffer(mInfo, g_vb_solid_face_colors_Data, sizeof(g_vb_solid_face_colors_Data),
                       sizeof(g_vb_solid_face_colors_Data[0]), false);
    init_descriptor_pool(mInfo, false);
    init_descriptor_set(mInfo);
    init_pipeline_cache(mInfo);
    init_pipeline(mInfo, mDepthPresent);

    mClearValues[0].color.float32[0]     = 0.2f;
    mClearValues[0].color.float32[1]     = 0.2f;
    mClearValues[0].color.float32[2]     = 0.2f;
    mClearValues[0].color.float32[3]     = 0.2f;
    mClearValues[1].depthStencil.depth   = 1.0f;
    mClearValues[1].depthStencil.stencil = 0;

    VkSemaphoreCreateInfo imageAcquiredSemaphoreCreateInfo;
    imageAcquiredSemaphoreCreateInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
    imageAcquiredSemaphoreCreateInfo.pNext = NULL;
    imageAcquiredSemaphoreCreateInfo.flags = 0;
    res = vkCreateSemaphore(mInfo.device, &imageAcquiredSemaphoreCreateInfo, NULL,
                            &mImageAcquiredSemaphore);
    ASSERT_EQ(VK_SUCCESS, res);

    VkFenceCreateInfo fenceInfo;
    fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
    fenceInfo.pNext = NULL;
    fenceInfo.flags = 0;
    res             = vkCreateFence(mInfo.device, &fenceInfo, NULL, &mDrawFence);
    ASSERT_EQ(VK_SUCCESS, res);
}

void VulkanCommandBufferPerfTest::step()
{
    for (int x = 0; x < mFrames; x++)
    {
        mInfo.current_buffer = x % mInfo.swapchainImageCount;

        // Get the index of the next available swapchain image:
        res = vkAcquireNextImageKHR(mInfo.device, mInfo.swap_chain, UINT64_MAX,
                                    mImageAcquiredSemaphore, VK_NULL_HANDLE, &mInfo.current_buffer);
        // Deal with the VK_SUBOPTIMAL_KHR and VK_ERROR_OUT_OF_DATE_KHR
        // return codes
        ASSERT_EQ(VK_SUCCESS, res);
        mCBImplementation(mInfo, mClearValues, mDrawFence, mImageAcquiredSemaphore, mBuffers);
    }
}

void VulkanCommandBufferPerfTest::TearDown()
{
    vkDestroySemaphore(mInfo.device, mImageAcquiredSemaphore, NULL);
    vkDestroyFence(mInfo.device, mDrawFence, NULL);
    destroy_pipeline(mInfo);
    destroy_pipeline_cache(mInfo);
    destroy_descriptor_pool(mInfo);
    destroy_vertex_buffer(mInfo);
    destroy_framebuffers(mInfo);
    destroy_shaders(mInfo);
    destroy_renderpass(mInfo);
    destroy_descriptor_and_pipeline_layouts(mInfo);
    destroy_uniform_buffer(mInfo);
    destroy_depth_buffer(mInfo);
    destroy_swap_chain(mInfo);
    destroy_command_buffer2_array(mInfo, mBuffers);
    destroy_command_buffer_array(mInfo, mBuffers);
    destroy_command_buffer(mInfo);
    destroy_command_pool(mInfo);
    destroy_device(mInfo);
    destroy_window(mInfo);
    destroy_instance(mInfo);
    ANGLEPerfTest::TearDown();
}

// Common code to present image used by all tests
void Present(sample_info &info, VkFence drawFence)
{
    // Now present the image in the window

    VkPresentInfoKHR present;
    present.sType              = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
    present.pNext              = NULL;
    present.swapchainCount     = 1;
    present.pSwapchains        = &info.swap_chain;
    present.pImageIndices      = &info.current_buffer;
    present.pWaitSemaphores    = NULL;
    present.waitSemaphoreCount = 0;
    present.pResults           = NULL;

    // Make sure command buffer is finished before presenting
    VkResult res;
    do
    {
        res = vkWaitForFences(info.device, 1, &drawFence, VK_TRUE, FENCE_TIMEOUT);
    } while (res == VK_TIMEOUT);
    vkResetFences(info.device, 1, &drawFence);

    ASSERT_EQ(VK_SUCCESS, res);
    res = vkQueuePresentKHR(info.present_queue, &present);
    ASSERT_EQ(VK_SUCCESS, res);
}

// 100 separate primary cmd buffers, each with 1 Draw
void PrimaryCommandBufferBenchmarkHundredIndividual(sample_info &info,
                                                    VkClearValue *clear_values,
                                                    VkFence drawFence,
                                                    VkSemaphore imageAcquiredSemaphore,
                                                    int numBuffers)
{
    VkResult res;

    VkRenderPassBeginInfo rpBegin;
    rpBegin.sType                    = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
    rpBegin.pNext                    = NULL;
    rpBegin.renderPass               = info.render_pass;
    rpBegin.framebuffer              = ANGLE_UNSAFE_TODO(info.framebuffers[info.current_buffer]);
    rpBegin.renderArea.offset.x      = 0;
    rpBegin.renderArea.offset.y      = 0;
    rpBegin.renderArea.extent.width  = info.width;
    rpBegin.renderArea.extent.height = info.height;
    rpBegin.clearValueCount          = 2;
    rpBegin.pClearValues             = clear_values;

    VkCommandBufferBeginInfo cmdBufferInfo = {};
    cmdBufferInfo.sType                    = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
    cmdBufferInfo.pNext                    = NULL;
    cmdBufferInfo.flags                    = 0;
    cmdBufferInfo.pInheritanceInfo         = NULL;

    for (int x = 0; x < numBuffers; x++)
    {
        vkBeginCommandBuffer(info.cmds[x], &cmdBufferInfo);
        vkCmdBeginRenderPass(info.cmds[x], &rpBegin, VK_SUBPASS_CONTENTS_INLINE);
        vkCmdBindPipeline(info.cmds[x], VK_PIPELINE_BIND_POINT_GRAPHICS, info.pipeline);
        vkCmdBindDescriptorSets(info.cmds[x], VK_PIPELINE_BIND_POINT_GRAPHICS, info.pipeline_layout,
                                0, NUM_DESCRIPTOR_SETS, info.desc_set.data(), 0, NULL);

        const VkDeviceSize offsets[1] = {0};
        vkCmdBindVertexBuffers(info.cmds[x], 0, 1, &info.vertex_buffer.buf, offsets);

        init_viewports_array(info, x);
        init_scissors_array(info, x);

        vkCmdDraw(info.cmds[x], 0, 1, 0, 0);
        vkCmdEndRenderPass(info.cmds[x]);
        res = vkEndCommandBuffer(info.cmds[x]);
        ASSERT_EQ(VK_SUCCESS, res);
    }

    VkPipelineStageFlags pipe_stage_flags = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
    VkSubmitInfo submitInfo[1]            = {};
    submitInfo[0].pNext                   = NULL;
    submitInfo[0].sType                   = VK_STRUCTURE_TYPE_SUBMIT_INFO;
    submitInfo[0].waitSemaphoreCount      = 1;
    submitInfo[0].pWaitSemaphores         = &imageAcquiredSemaphore;
    submitInfo[0].pWaitDstStageMask       = &pipe_stage_flags;
    submitInfo[0].commandBufferCount      = numBuffers;
    submitInfo[0].pCommandBuffers         = info.cmds.data();
    submitInfo[0].signalSemaphoreCount    = 0;
    submitInfo[0].pSignalSemaphores       = NULL;

    // Queue the command buffer for execution
    res = vkQueueSubmit(info.graphics_queue, 1, submitInfo, drawFence);
    ASSERT_EQ(VK_SUCCESS, res);

    Present(info, drawFence);
}

// 100 of the same Draw cmds in the same primary cmd buffer
void PrimaryCommandBufferBenchmarkOneWithOneHundred(sample_info &info,
                                                    VkClearValue *clear_values,
                                                    VkFence drawFence,
                                                    VkSemaphore imageAcquiredSemaphore,
                                                    int numBuffers)
{
    VkResult res;

    VkRenderPassBeginInfo rpBegin;
    rpBegin.sType                    = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
    rpBegin.pNext                    = NULL;
    rpBegin.renderPass               = info.render_pass;
    rpBegin.framebuffer              = ANGLE_UNSAFE_TODO(info.framebuffers[info.current_buffer]);
    rpBegin.renderArea.offset.x      = 0;
    rpBegin.renderArea.offset.y      = 0;
    rpBegin.renderArea.extent.width  = info.width;
    rpBegin.renderArea.extent.height = info.height;
    rpBegin.clearValueCount          = 2;
    rpBegin.pClearValues             = clear_values;

    VkCommandBufferBeginInfo cmdBufferInfo = {};
    cmdBufferInfo.sType                    = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
    cmdBufferInfo.pNext                    = NULL;
    cmdBufferInfo.flags                    = 0;
    cmdBufferInfo.pInheritanceInfo         = NULL;

    vkBeginCommandBuffer(info.cmd, &cmdBufferInfo);
    for (int x = 0; x < numBuffers; x++)
    {
        vkCmdBeginRenderPass(info.cmd, &rpBegin, VK_SUBPASS_CONTENTS_INLINE);
        vkCmdBindPipeline(info.cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, info.pipeline);
        vkCmdBindDescriptorSets(info.cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, info.pipeline_layout, 0,
                                NUM_DESCRIPTOR_SETS, info.desc_set.data(), 0, NULL);

        const VkDeviceSize offsets[1] = {0};
        vkCmdBindVertexBuffers(info.cmd, 0, 1, &info.vertex_buffer.buf, offsets);

        init_viewports(info);
        init_scissors(info);

        vkCmdDraw(info.cmd, 0, 1, 0, 0);
        vkCmdEndRenderPass(info.cmd);
    }
    res = vkEndCommandBuffer(info.cmd);
    ASSERT_EQ(VK_SUCCESS, res);

    const VkCommandBuffer cmd_bufs[]      = {info.cmd};
    VkPipelineStageFlags pipe_stage_flags = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
    VkSubmitInfo submitInfo[1]            = {};
    submitInfo[0].pNext                   = NULL;
    submitInfo[0].sType                   = VK_STRUCTURE_TYPE_SUBMIT_INFO;
    submitInfo[0].waitSemaphoreCount      = 1;
    submitInfo[0].pWaitSemaphores         = &imageAcquiredSemaphore;
    submitInfo[0].pWaitDstStageMask       = &pipe_stage_flags;
    submitInfo[0].commandBufferCount      = 1;
    submitInfo[0].pCommandBuffers         = cmd_bufs;
    submitInfo[0].signalSemaphoreCount    = 0;
    submitInfo[0].pSignalSemaphores       = NULL;

    // Queue the command buffer for execution
    res = vkQueueSubmit(info.graphics_queue, 1, submitInfo, drawFence);
    ASSERT_EQ(VK_SUCCESS, res);

    Present(info, drawFence);
}

// 100 separate secondary cmd buffers, each with 1 Draw
void SecondaryCommandBufferBenchmark(sample_info &info,
                                     VkClearValue *clear_values,
                                     VkFence drawFence,
                                     VkSemaphore imageAcquiredSemaphore,
                                     int numBuffers)
{
    VkResult res;

    // Record Secondary Command Buffer
    VkCommandBufferInheritanceInfo inheritInfo = {};
    inheritInfo.sType                          = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
    inheritInfo.pNext                          = NULL;
    inheritInfo.renderPass                     = info.render_pass;
    inheritInfo.subpass                        = 0;
    inheritInfo.framebuffer = ANGLE_UNSAFE_TODO(info.framebuffers[info.current_buffer]);
    inheritInfo.occlusionQueryEnable           = false;
    inheritInfo.queryFlags                     = 0;
    inheritInfo.pipelineStatistics             = 0;

    VkCommandBufferBeginInfo secondaryCommandBufferInfo = {};
    secondaryCommandBufferInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
    secondaryCommandBufferInfo.pNext = NULL;
    secondaryCommandBufferInfo.flags = VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT |
                                       VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT;
    secondaryCommandBufferInfo.pInheritanceInfo = &inheritInfo;

    for (int x = 0; x < numBuffers; x++)
    {
        vkBeginCommandBuffer(info.cmd2s[x], &secondaryCommandBufferInfo);
        vkCmdBindPipeline(info.cmd2s[x], VK_PIPELINE_BIND_POINT_GRAPHICS, info.pipeline);
        vkCmdBindDescriptorSets(info.cmd2s[x], VK_PIPELINE_BIND_POINT_GRAPHICS,
                                info.pipeline_layout, 0, NUM_DESCRIPTOR_SETS, info.desc_set.data(),
                                0, NULL);
        const VkDeviceSize offsets[1] = {0};
        vkCmdBindVertexBuffers(info.cmd2s[x], 0, 1, &info.vertex_buffer.buf, offsets);
        init_viewports2_array(info, x);
        init_scissors2_array(info, x);
        vkCmdDraw(info.cmd2s[x], 0, 1, 0, 0);
        vkEndCommandBuffer(info.cmd2s[x]);
    }
    // Record Secondary Command Buffer End

    // Record Primary Command Buffer Begin
    VkRenderPassBeginInfo rpBegin;
    rpBegin.sType                    = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
    rpBegin.pNext                    = NULL;
    rpBegin.renderPass               = info.render_pass;
    rpBegin.framebuffer              = ANGLE_UNSAFE_TODO(info.framebuffers[info.current_buffer]);
    rpBegin.renderArea.offset.x      = 0;
    rpBegin.renderArea.offset.y      = 0;
    rpBegin.renderArea.extent.width  = info.width;
    rpBegin.renderArea.extent.height = info.height;
    rpBegin.clearValueCount          = 2;
    rpBegin.pClearValues             = clear_values;

    VkCommandBufferBeginInfo primaryCommandBufferInfo = {};
    primaryCommandBufferInfo.sType                    = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
    primaryCommandBufferInfo.pNext                    = NULL;
    primaryCommandBufferInfo.flags                    = 0;
    primaryCommandBufferInfo.pInheritanceInfo         = NULL;

    vkBeginCommandBuffer(info.cmd, &primaryCommandBufferInfo);
    for (int x = 0; x < numBuffers; x++)
    {
        vkCmdBeginRenderPass(info.cmd, &rpBegin, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
        vkCmdExecuteCommands(info.cmd, 1, &info.cmd2s[x]);
        vkCmdEndRenderPass(info.cmd);
    }
    vkEndCommandBuffer(info.cmd);
    // Record Primary Command Buffer End

    const VkCommandBuffer cmd_bufs[]      = {info.cmd};
    VkPipelineStageFlags pipe_stage_flags = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
    VkSubmitInfo submitInfo[1]            = {};
    submitInfo[0].pNext                   = NULL;
    submitInfo[0].sType                   = VK_STRUCTURE_TYPE_SUBMIT_INFO;
    submitInfo[0].waitSemaphoreCount      = 1;
    submitInfo[0].pWaitSemaphores         = &imageAcquiredSemaphore;
    submitInfo[0].pWaitDstStageMask       = &pipe_stage_flags;
    submitInfo[0].commandBufferCount      = 1;
    submitInfo[0].pCommandBuffers         = cmd_bufs;
    submitInfo[0].signalSemaphoreCount    = 0;
    submitInfo[0].pSignalSemaphores       = NULL;

    // Queue the command buffer for execution
    res = vkQueueSubmit(info.graphics_queue, 1, submitInfo, drawFence);
    ASSERT_EQ(VK_SUCCESS, res);

    Present(info, drawFence);
}

// Details on the following functions that stress various cmd buffer reset methods.
// All of these functions wrap the SecondaryCommandBufferBenchmark() test above,
// adding additional overhead with various reset methods.
// -CommandPoolDestroyBenchmark: Reset command buffers by destroying and re-creating
//   command buffer pool.
// -CommandPoolHardResetBenchmark: Reset the command pool w/ the RELEASE_RESOURCES
//   bit set.
// -CommandPoolSoftResetBenchmark: Reset to command pool w/o the RELEASE_RESOURCES
//   bit set.
// -CommandBufferExplicitHardResetBenchmark: Reset each individual command buffer
//   w/ the RELEASE_RESOURCES bit set.
// -CommandBufferExplicitSoftResetBenchmark: Reset each individual command buffer
//   w/o the RELEASE_RESOURCES bit set.
// -CommandBufferImplicitResetBenchmark: Reset each individual command buffer
//   implicitly by calling "Begin" on previously used cmd buffer.

void CommandPoolDestroyBenchmark(sample_info &info,
                                 VkClearValue *clear_values,
                                 VkFence drawFence,
                                 VkSemaphore imageAcquiredSemaphore,
                                 int numBuffers)
{
    // Save setup cmd buffer data to be restored
    auto saved_cmd_pool = info.cmd_pool;
    auto saved_cb       = info.cmd;
    auto saved_cb2s     = info.cmd2s;
    // Now re-allocate & destroy cmd buffers to stress those calls
    init_command_pool(info, 0);
    init_command_buffer2_array(info, numBuffers);

    SecondaryCommandBufferBenchmark(info, clear_values, drawFence, imageAcquiredSemaphore,
                                    numBuffers);

    destroy_command_pool(info);

    // Restore original cmd buffer data for cleanup
    info.cmd_pool = saved_cmd_pool;
    info.cmd      = saved_cb;
    info.cmd2s    = saved_cb2s;
}

void CommandPoolHardResetBenchmark(sample_info &info,
                                   VkClearValue *clear_values,
                                   VkFence drawFence,
                                   VkSemaphore imageAcquiredSemaphore,
                                   int numBuffers)
{
    SecondaryCommandBufferBenchmark(info, clear_values, drawFence, imageAcquiredSemaphore,
                                    numBuffers);
    reset_command_pool(info, VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT);
}

void CommandPoolSoftResetBenchmark(sample_info &info,
                                   VkClearValue *clear_values,
                                   VkFence drawFence,
                                   VkSemaphore imageAcquiredSemaphore,
                                   int numBuffers)
{
    SecondaryCommandBufferBenchmark(info, clear_values, drawFence, imageAcquiredSemaphore,
                                    numBuffers);
    reset_command_pool(info, 0);
}

void CommandBufferExplicitHardResetBenchmark(sample_info &info,
                                             VkClearValue *clear_values,
                                             VkFence drawFence,
                                             VkSemaphore imageAcquiredSemaphore,
                                             int numBuffers)
{
    SecondaryCommandBufferBenchmark(info, clear_values, drawFence, imageAcquiredSemaphore,
                                    numBuffers);
    // Explicitly resetting cmd buffers
    reset_command_buffer2_array(info, VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT);
}

void CommandBufferExplicitSoftResetBenchmark(sample_info &info,
                                             VkClearValue *clear_values,
                                             VkFence drawFence,
                                             VkSemaphore imageAcquiredSemaphore,
                                             int numBuffers)
{
    SecondaryCommandBufferBenchmark(info, clear_values, drawFence, imageAcquiredSemaphore,
                                    numBuffers);
    // Explicitly resetting cmd buffers w/ soft reset (don't release resources)
    reset_command_buffer2_array(info, 0);
}

void CommandBufferImplicitResetBenchmark(sample_info &info,
                                         VkClearValue *clear_values,
                                         VkFence drawFence,
                                         VkSemaphore imageAcquiredSemaphore,
                                         int numBuffers)
{
    // Repeated call SCBBenchmark & BeginCmdBuffer calls will implicitly reset each cmd buffer
    SecondaryCommandBufferBenchmark(info, clear_values, drawFence, imageAcquiredSemaphore,
                                    numBuffers);
}

CommandBufferTestParams PrimaryCBHundredIndividualParams()
{
    CommandBufferTestParams params;
    params.CBImplementation = PrimaryCommandBufferBenchmarkHundredIndividual;
    params.story            = "_PrimaryCB_Submit_100_With_1_Draw";
    return params;
}

CommandBufferTestParams PrimaryCBOneWithOneHundredParams()
{
    CommandBufferTestParams params;
    params.CBImplementation = PrimaryCommandBufferBenchmarkOneWithOneHundred;
    params.story            = "_PrimaryCB_Submit_1_With_100_Draw";
    return params;
}

CommandBufferTestParams SecondaryCBParams()
{
    CommandBufferTestParams params;
    params.CBImplementation = SecondaryCommandBufferBenchmark;
    params.story            = "_SecondaryCB_Submit_1_With_100_Draw_In_Individual_Secondary";
    return params;
}

CommandBufferTestParams CommandPoolDestroyParams()
{
    CommandBufferTestParams params;
    params.CBImplementation = CommandPoolDestroyBenchmark;
    params.story            = "_Reset_CBs_With_Destroy_Command_Pool";
    return params;
}

CommandBufferTestParams CommandPoolHardResetParams()
{
    CommandBufferTestParams params;
    params.CBImplementation = CommandPoolHardResetBenchmark;
    params.story            = "_Reset_CBs_With_Hard_Reset_Command_Pool";
    return params;
}

CommandBufferTestParams CommandPoolSoftResetParams()
{
    CommandBufferTestParams params;
    params.CBImplementation = CommandPoolSoftResetBenchmark;
    params.story            = "_Reset_CBs_With_Soft_Reset_Command_Pool";
    return params;
}

CommandBufferTestParams CommandBufferExplicitHardResetParams()
{
    CommandBufferTestParams params;
    params.CBImplementation = CommandBufferExplicitHardResetBenchmark;
    params.story            = "_Reset_CBs_With_Explicit_Hard_Reset_Command_Buffers";
    return params;
}

CommandBufferTestParams CommandBufferExplicitSoftResetParams()
{
    CommandBufferTestParams params;
    params.CBImplementation = CommandBufferExplicitSoftResetBenchmark;
    params.story            = "_Reset_CBs_With_Explicit_Soft_Reset_Command_Buffers";
    return params;
}

CommandBufferTestParams CommandBufferImplicitResetParams()
{
    CommandBufferTestParams params;
    params.CBImplementation = CommandBufferImplicitResetBenchmark;
    params.story            = "_Reset_CBs_With_Implicit_Reset_Command_Buffers";
    return params;
}

TEST_P(VulkanCommandBufferPerfTest, Run)
{
    run();
}

INSTANTIATE_TEST_SUITE_P(,
                         VulkanCommandBufferPerfTest,
                         ::testing::Values(PrimaryCBHundredIndividualParams(),
                                           PrimaryCBOneWithOneHundredParams(),
                                           SecondaryCBParams(),
                                           CommandPoolDestroyParams(),
                                           CommandPoolHardResetParams(),
                                           CommandPoolSoftResetParams(),
                                           CommandBufferExplicitHardResetParams(),
                                           CommandBufferExplicitSoftResetParams(),
                                           CommandBufferImplicitResetParams()));
