//
// 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.
//
// VulkanPipelineCachePerf:
//   Performance benchmark for the Vulkan Pipeline cache.

#include "ANGLEPerfTest.h"

#include "libANGLE/renderer/vulkan/vk_cache_utils.h"
#include "libANGLE/renderer/vulkan/vk_helpers.h"
#include "libANGLE/renderer/vulkan/vk_renderer.h"
#include "util/random_utils.h"

using namespace rx;

namespace
{
constexpr unsigned int kIterationsPerStep = 100;

struct Params
{
    bool withDynamicState = false;
};

class VulkanPipelineCachePerfTest : public ANGLEPerfTest,
                                    public ::testing::WithParamInterface<Params>
{
  public:
    VulkanPipelineCachePerfTest();
    ~VulkanPipelineCachePerfTest();

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

    GraphicsPipelineCache<GraphicsPipelineDescCompleteHash> mCache;
    angle::RNG mRNG;

    std::vector<vk::GraphicsPipelineDesc> mCacheHits;
    std::vector<vk::GraphicsPipelineDesc> mCacheMisses;
    size_t mMissIndex = 0;

  private:
    void randomizeDesc(vk::GraphicsPipelineDesc *desc);
};

VulkanPipelineCachePerfTest::VulkanPipelineCachePerfTest()
    : ANGLEPerfTest("VulkanPipelineCachePerf", "", "", kIterationsPerStep), mRNG(0x12345678u)
{}

VulkanPipelineCachePerfTest::~VulkanPipelineCachePerfTest()
{
    mCache.reset();
}

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

    // Insert a number of random pipeline states.
    for (int pipelineCount = 0; pipelineCount < 100; ++pipelineCount)
    {
        vk::Pipeline pipeline;
        vk::GraphicsPipelineDesc desc;
        randomizeDesc(&desc);

        if (pipelineCount < 10)
        {
            mCacheHits.push_back(desc);
        }
        mCache.populate(desc, std::move(pipeline), nullptr);
    }

    for (int missCount = 0; missCount < 10000; ++missCount)
    {
        vk::GraphicsPipelineDesc desc;
        randomizeDesc(&desc);
        mCacheMisses.push_back(desc);
    }
}

void VulkanPipelineCachePerfTest::randomizeDesc(vk::GraphicsPipelineDesc *desc)
{
    std::vector<uint8_t> bytes(sizeof(vk::GraphicsPipelineDesc));
    FillVectorWithRandomUBytes(&mRNG, &bytes);
    memcpy(desc, bytes.data(), sizeof(vk::GraphicsPipelineDesc));

    desc->setSupportsDynamicStateForTest(GetParam().withDynamicState);
}

void VulkanPipelineCachePerfTest::step()
{
    vk::RenderPass rp;
    vk::PipelineLayout pl;
    vk::PipelineCache pc;
    vk::PipelineCacheAccess spc;
    vk::ShaderModulePtr vs = vk::ShaderModulePtr::MakeShared(VK_NULL_HANDLE);
    vk::ShaderModulePtr fs = vk::ShaderModulePtr::MakeShared(VK_NULL_HANDLE);
    vk::ShaderModuleMap ssm;
    const vk::GraphicsPipelineDesc *desc = nullptr;
    vk::PipelineHelper *result           = nullptr;

    // The Vulkan handle types are difficult to cast to without #ifdefs.
    vs->setHandle((VkShaderModule)1);
    fs->setHandle((VkShaderModule)2);

    ssm[gl::ShaderType::Vertex]   = vs;
    ssm[gl::ShaderType::Fragment] = fs;

    spc.init(&pc, nullptr);

    vk::SpecializationConstants defaultSpecConsts{};

    for (unsigned int iteration = 0; iteration < kIterationsPerStep; ++iteration)
    {
        for (const auto &hit : mCacheHits)
        {
            if (!mCache.getPipeline(hit, &desc, &result))
            {
                (void)mCache.createPipeline(VK_NULL_HANDLE, &spc, rp, pl,
                                            {&ssm, &defaultSpecConsts}, PipelineSource::Draw, hit,
                                            &desc, &result);
            }
        }
    }

    for (int missCount = 0; missCount < 20 && mMissIndex < mCacheMisses.size();
         ++missCount, ++mMissIndex)
    {
        const auto &miss = mCacheMisses[mMissIndex];
        if (!mCache.getPipeline(miss, &desc, &result))
        {
            (void)mCache.createPipeline(VK_NULL_HANDLE, &spc, rp, pl, {&ssm, &defaultSpecConsts},
                                        PipelineSource::Draw, miss, &desc, &result);
        }
    }

    vs->setHandle(VK_NULL_HANDLE);
    fs->setHandle(VK_NULL_HANDLE);
}

}  // anonymous namespace

// Test performance of pipeline hash and look up in Vulkan
TEST_P(VulkanPipelineCachePerfTest, Run)
{
    run();
}

INSTANTIATE_TEST_SUITE_P(,
                         VulkanPipelineCachePerfTest,
                         ::testing::ValuesIn(std::vector<Params>{{Params{false}, Params{true}}}));
