xref: /aosp_15_r20/external/angle/src/tests/perf_tests/VulkanPipelineCachePerf.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2018 The ANGLE Project Authors. All rights reserved.
3*8975f5c5SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
4*8975f5c5SAndroid Build Coastguard Worker // found in the LICENSE file.
5*8975f5c5SAndroid Build Coastguard Worker //
6*8975f5c5SAndroid Build Coastguard Worker // VulkanPipelineCachePerf:
7*8975f5c5SAndroid Build Coastguard Worker //   Performance benchmark for the Vulkan Pipeline cache.
8*8975f5c5SAndroid Build Coastguard Worker 
9*8975f5c5SAndroid Build Coastguard Worker #include "ANGLEPerfTest.h"
10*8975f5c5SAndroid Build Coastguard Worker 
11*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/vulkan/vk_cache_utils.h"
12*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/vulkan/vk_helpers.h"
13*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/vulkan/vk_renderer.h"
14*8975f5c5SAndroid Build Coastguard Worker #include "util/random_utils.h"
15*8975f5c5SAndroid Build Coastguard Worker 
16*8975f5c5SAndroid Build Coastguard Worker using namespace rx;
17*8975f5c5SAndroid Build Coastguard Worker 
18*8975f5c5SAndroid Build Coastguard Worker namespace
19*8975f5c5SAndroid Build Coastguard Worker {
20*8975f5c5SAndroid Build Coastguard Worker constexpr unsigned int kIterationsPerStep = 100;
21*8975f5c5SAndroid Build Coastguard Worker 
22*8975f5c5SAndroid Build Coastguard Worker struct Params
23*8975f5c5SAndroid Build Coastguard Worker {
24*8975f5c5SAndroid Build Coastguard Worker     bool withDynamicState = false;
25*8975f5c5SAndroid Build Coastguard Worker };
26*8975f5c5SAndroid Build Coastguard Worker 
27*8975f5c5SAndroid Build Coastguard Worker class VulkanPipelineCachePerfTest : public ANGLEPerfTest,
28*8975f5c5SAndroid Build Coastguard Worker                                     public ::testing::WithParamInterface<Params>
29*8975f5c5SAndroid Build Coastguard Worker {
30*8975f5c5SAndroid Build Coastguard Worker   public:
31*8975f5c5SAndroid Build Coastguard Worker     VulkanPipelineCachePerfTest();
32*8975f5c5SAndroid Build Coastguard Worker     ~VulkanPipelineCachePerfTest();
33*8975f5c5SAndroid Build Coastguard Worker 
34*8975f5c5SAndroid Build Coastguard Worker     void SetUp() override;
35*8975f5c5SAndroid Build Coastguard Worker     void step() override;
36*8975f5c5SAndroid Build Coastguard Worker 
37*8975f5c5SAndroid Build Coastguard Worker     GraphicsPipelineCache<GraphicsPipelineDescCompleteHash> mCache;
38*8975f5c5SAndroid Build Coastguard Worker     angle::RNG mRNG;
39*8975f5c5SAndroid Build Coastguard Worker 
40*8975f5c5SAndroid Build Coastguard Worker     std::vector<vk::GraphicsPipelineDesc> mCacheHits;
41*8975f5c5SAndroid Build Coastguard Worker     std::vector<vk::GraphicsPipelineDesc> mCacheMisses;
42*8975f5c5SAndroid Build Coastguard Worker     size_t mMissIndex = 0;
43*8975f5c5SAndroid Build Coastguard Worker 
44*8975f5c5SAndroid Build Coastguard Worker   private:
45*8975f5c5SAndroid Build Coastguard Worker     void randomizeDesc(vk::GraphicsPipelineDesc *desc);
46*8975f5c5SAndroid Build Coastguard Worker };
47*8975f5c5SAndroid Build Coastguard Worker 
VulkanPipelineCachePerfTest()48*8975f5c5SAndroid Build Coastguard Worker VulkanPipelineCachePerfTest::VulkanPipelineCachePerfTest()
49*8975f5c5SAndroid Build Coastguard Worker     : ANGLEPerfTest("VulkanPipelineCachePerf", "", "", kIterationsPerStep), mRNG(0x12345678u)
50*8975f5c5SAndroid Build Coastguard Worker {}
51*8975f5c5SAndroid Build Coastguard Worker 
~VulkanPipelineCachePerfTest()52*8975f5c5SAndroid Build Coastguard Worker VulkanPipelineCachePerfTest::~VulkanPipelineCachePerfTest()
53*8975f5c5SAndroid Build Coastguard Worker {
54*8975f5c5SAndroid Build Coastguard Worker     mCache.reset();
55*8975f5c5SAndroid Build Coastguard Worker }
56*8975f5c5SAndroid Build Coastguard Worker 
SetUp()57*8975f5c5SAndroid Build Coastguard Worker void VulkanPipelineCachePerfTest::SetUp()
58*8975f5c5SAndroid Build Coastguard Worker {
59*8975f5c5SAndroid Build Coastguard Worker     ANGLEPerfTest::SetUp();
60*8975f5c5SAndroid Build Coastguard Worker 
61*8975f5c5SAndroid Build Coastguard Worker     // Insert a number of random pipeline states.
62*8975f5c5SAndroid Build Coastguard Worker     for (int pipelineCount = 0; pipelineCount < 100; ++pipelineCount)
63*8975f5c5SAndroid Build Coastguard Worker     {
64*8975f5c5SAndroid Build Coastguard Worker         vk::Pipeline pipeline;
65*8975f5c5SAndroid Build Coastguard Worker         vk::GraphicsPipelineDesc desc;
66*8975f5c5SAndroid Build Coastguard Worker         randomizeDesc(&desc);
67*8975f5c5SAndroid Build Coastguard Worker 
68*8975f5c5SAndroid Build Coastguard Worker         if (pipelineCount < 10)
69*8975f5c5SAndroid Build Coastguard Worker         {
70*8975f5c5SAndroid Build Coastguard Worker             mCacheHits.push_back(desc);
71*8975f5c5SAndroid Build Coastguard Worker         }
72*8975f5c5SAndroid Build Coastguard Worker         mCache.populate(desc, std::move(pipeline), nullptr);
73*8975f5c5SAndroid Build Coastguard Worker     }
74*8975f5c5SAndroid Build Coastguard Worker 
75*8975f5c5SAndroid Build Coastguard Worker     for (int missCount = 0; missCount < 10000; ++missCount)
76*8975f5c5SAndroid Build Coastguard Worker     {
77*8975f5c5SAndroid Build Coastguard Worker         vk::GraphicsPipelineDesc desc;
78*8975f5c5SAndroid Build Coastguard Worker         randomizeDesc(&desc);
79*8975f5c5SAndroid Build Coastguard Worker         mCacheMisses.push_back(desc);
80*8975f5c5SAndroid Build Coastguard Worker     }
81*8975f5c5SAndroid Build Coastguard Worker }
82*8975f5c5SAndroid Build Coastguard Worker 
randomizeDesc(vk::GraphicsPipelineDesc * desc)83*8975f5c5SAndroid Build Coastguard Worker void VulkanPipelineCachePerfTest::randomizeDesc(vk::GraphicsPipelineDesc *desc)
84*8975f5c5SAndroid Build Coastguard Worker {
85*8975f5c5SAndroid Build Coastguard Worker     std::vector<uint8_t> bytes(sizeof(vk::GraphicsPipelineDesc));
86*8975f5c5SAndroid Build Coastguard Worker     FillVectorWithRandomUBytes(&mRNG, &bytes);
87*8975f5c5SAndroid Build Coastguard Worker     memcpy(desc, bytes.data(), sizeof(vk::GraphicsPipelineDesc));
88*8975f5c5SAndroid Build Coastguard Worker 
89*8975f5c5SAndroid Build Coastguard Worker     desc->setSupportsDynamicStateForTest(GetParam().withDynamicState);
90*8975f5c5SAndroid Build Coastguard Worker }
91*8975f5c5SAndroid Build Coastguard Worker 
step()92*8975f5c5SAndroid Build Coastguard Worker void VulkanPipelineCachePerfTest::step()
93*8975f5c5SAndroid Build Coastguard Worker {
94*8975f5c5SAndroid Build Coastguard Worker     vk::RenderPass rp;
95*8975f5c5SAndroid Build Coastguard Worker     vk::PipelineLayout pl;
96*8975f5c5SAndroid Build Coastguard Worker     vk::PipelineCache pc;
97*8975f5c5SAndroid Build Coastguard Worker     vk::PipelineCacheAccess spc;
98*8975f5c5SAndroid Build Coastguard Worker     vk::ShaderModulePtr vs = vk::ShaderModulePtr::MakeShared(VK_NULL_HANDLE);
99*8975f5c5SAndroid Build Coastguard Worker     vk::ShaderModulePtr fs = vk::ShaderModulePtr::MakeShared(VK_NULL_HANDLE);
100*8975f5c5SAndroid Build Coastguard Worker     vk::ShaderModuleMap ssm;
101*8975f5c5SAndroid Build Coastguard Worker     const vk::GraphicsPipelineDesc *desc = nullptr;
102*8975f5c5SAndroid Build Coastguard Worker     vk::PipelineHelper *result           = nullptr;
103*8975f5c5SAndroid Build Coastguard Worker 
104*8975f5c5SAndroid Build Coastguard Worker     // The Vulkan handle types are difficult to cast to without #ifdefs.
105*8975f5c5SAndroid Build Coastguard Worker     vs->setHandle((VkShaderModule)1);
106*8975f5c5SAndroid Build Coastguard Worker     fs->setHandle((VkShaderModule)2);
107*8975f5c5SAndroid Build Coastguard Worker 
108*8975f5c5SAndroid Build Coastguard Worker     ssm[gl::ShaderType::Vertex]   = vs;
109*8975f5c5SAndroid Build Coastguard Worker     ssm[gl::ShaderType::Fragment] = fs;
110*8975f5c5SAndroid Build Coastguard Worker 
111*8975f5c5SAndroid Build Coastguard Worker     spc.init(&pc, nullptr);
112*8975f5c5SAndroid Build Coastguard Worker 
113*8975f5c5SAndroid Build Coastguard Worker     vk::SpecializationConstants defaultSpecConsts{};
114*8975f5c5SAndroid Build Coastguard Worker 
115*8975f5c5SAndroid Build Coastguard Worker     for (unsigned int iteration = 0; iteration < kIterationsPerStep; ++iteration)
116*8975f5c5SAndroid Build Coastguard Worker     {
117*8975f5c5SAndroid Build Coastguard Worker         for (const auto &hit : mCacheHits)
118*8975f5c5SAndroid Build Coastguard Worker         {
119*8975f5c5SAndroid Build Coastguard Worker             if (!mCache.getPipeline(hit, &desc, &result))
120*8975f5c5SAndroid Build Coastguard Worker             {
121*8975f5c5SAndroid Build Coastguard Worker                 (void)mCache.createPipeline(VK_NULL_HANDLE, &spc, rp, pl, ssm, defaultSpecConsts,
122*8975f5c5SAndroid Build Coastguard Worker                                             PipelineSource::Draw, hit, &desc, &result);
123*8975f5c5SAndroid Build Coastguard Worker             }
124*8975f5c5SAndroid Build Coastguard Worker         }
125*8975f5c5SAndroid Build Coastguard Worker     }
126*8975f5c5SAndroid Build Coastguard Worker 
127*8975f5c5SAndroid Build Coastguard Worker     for (int missCount = 0; missCount < 20 && mMissIndex < mCacheMisses.size();
128*8975f5c5SAndroid Build Coastguard Worker          ++missCount, ++mMissIndex)
129*8975f5c5SAndroid Build Coastguard Worker     {
130*8975f5c5SAndroid Build Coastguard Worker         const auto &miss = mCacheMisses[mMissIndex];
131*8975f5c5SAndroid Build Coastguard Worker         if (!mCache.getPipeline(miss, &desc, &result))
132*8975f5c5SAndroid Build Coastguard Worker         {
133*8975f5c5SAndroid Build Coastguard Worker             (void)mCache.createPipeline(VK_NULL_HANDLE, &spc, rp, pl, ssm, defaultSpecConsts,
134*8975f5c5SAndroid Build Coastguard Worker                                         PipelineSource::Draw, miss, &desc, &result);
135*8975f5c5SAndroid Build Coastguard Worker         }
136*8975f5c5SAndroid Build Coastguard Worker     }
137*8975f5c5SAndroid Build Coastguard Worker 
138*8975f5c5SAndroid Build Coastguard Worker     vs->setHandle(VK_NULL_HANDLE);
139*8975f5c5SAndroid Build Coastguard Worker     fs->setHandle(VK_NULL_HANDLE);
140*8975f5c5SAndroid Build Coastguard Worker }
141*8975f5c5SAndroid Build Coastguard Worker 
142*8975f5c5SAndroid Build Coastguard Worker }  // anonymous namespace
143*8975f5c5SAndroid Build Coastguard Worker 
144*8975f5c5SAndroid Build Coastguard Worker // Test performance of pipeline hash and look up in Vulkan
TEST_P(VulkanPipelineCachePerfTest,Run)145*8975f5c5SAndroid Build Coastguard Worker TEST_P(VulkanPipelineCachePerfTest, Run)
146*8975f5c5SAndroid Build Coastguard Worker {
147*8975f5c5SAndroid Build Coastguard Worker     run();
148*8975f5c5SAndroid Build Coastguard Worker }
149*8975f5c5SAndroid Build Coastguard Worker 
150*8975f5c5SAndroid Build Coastguard Worker INSTANTIATE_TEST_SUITE_P(,
151*8975f5c5SAndroid Build Coastguard Worker                          VulkanPipelineCachePerfTest,
152*8975f5c5SAndroid Build Coastguard Worker                          ::testing::ValuesIn(std::vector<Params>{{Params{false}, Params{true}}}));
153