xref: /aosp_15_r20/external/deqp/external/vulkancts/framework/vulkan/vkResourceInterface.hpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1 #ifndef _VKRESOURCEINTERFACE_HPP
2 #define _VKRESOURCEINTERFACE_HPP
3 /*-------------------------------------------------------------------------
4  * Vulkan CTS Framework
5  * --------------------
6  *
7  * Copyright (c) 2021 The Khronos Group Inc.
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  *//*!
22  * \file
23  * \brief Defines class for handling resources ( programs, pipelines, files, etc. )
24  *//*--------------------------------------------------------------------*/
25 
26 #include "vkDefs.hpp"
27 #include "tcuTestLog.hpp"
28 #include "tcuTestContext.hpp"
29 #include "vkPrograms.hpp"
30 #include "vkBinaryRegistry.hpp"
31 #include "deSharedPtr.hpp"
32 #include "deDefs.hpp"
33 #include <map>
34 #ifdef CTS_USES_VULKANSC
35 #include "vksClient.hpp"
36 #include "tcuMaybe.hpp"
37 //    #include "vksStructsVKSC.hpp"
38 #endif // CTS_USES_VULKANSC
39 
40 namespace vk
41 {
42 
43 class ResourceInterface
44 {
45 public:
46     ResourceInterface(tcu::TestContext &testCtx);
47     virtual ~ResourceInterface();
48 
49     virtual void initDevice(DeviceInterface &deviceInterface, VkDevice device) = 0;
50     // use deinitDevice when your DeviceDriverSC is created and removed inside TestInstance
51     virtual void deinitDevice(VkDevice device) = 0;
52 
53     virtual void initTestCase(const std::string &casePath);
54     const std::string &getCasePath() const;
55 
56     // buildProgram
57     template <typename InfoType, typename IteratorType>
58     vk::ProgramBinary *buildProgram(const std::string &casePath, IteratorType iter,
59                                     const vk::BinaryRegistryReader &prebuiltBinRegistry,
60                                     vk::BinaryCollection *progCollection);
61 
62 #ifdef CTS_USES_VULKANSC
63     void initApiVersion(const uint32_t version);
64     bool isVulkanSC(void) const;
65 
66     uint64_t incResourceCounter();
67     std::mutex &getStatMutex();
68     VkDeviceObjectReservationCreateInfo &getStatCurrent();
69     VkDeviceObjectReservationCreateInfo &getStatMax();
70     const VkDeviceObjectReservationCreateInfo &getStatMax() const;
71     void setHandleDestroy(bool value);
72     bool isEnabledHandleDestroy() const;
73 
74     virtual void registerDeviceFeatures(VkDevice device, const VkDeviceCreateInfo *pCreateInfo) const              = 0;
75     virtual void unregisterDeviceFeatures(VkDevice device) const                                                   = 0;
76     virtual VkResult createShaderModule(VkDevice device, const VkShaderModuleCreateInfo *pCreateInfo,
77                                         const VkAllocationCallbacks *pAllocator, VkShaderModule *pShaderModule,
78                                         bool normalMode) const                                                     = 0;
79     virtual VkResult createGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount,
80                                              const VkGraphicsPipelineCreateInfo *pCreateInfos,
81                                              const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
82                                              bool normalMode) const                                                = 0;
83     virtual VkResult createComputePipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount,
84                                             const VkComputePipelineCreateInfo *pCreateInfos,
85                                             const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
86                                             bool normalMode) const                                                 = 0;
87     virtual void destroyPipeline(VkDevice device, VkPipeline pipeline,
88                                  const VkAllocationCallbacks *pAllocator) const                                    = 0;
89     virtual void createRenderPass(VkDevice device, const VkRenderPassCreateInfo *pCreateInfo,
90                                   const VkAllocationCallbacks *pAllocator, VkRenderPass *pRenderPass) const        = 0;
91     virtual void createRenderPass2(VkDevice device, const VkRenderPassCreateInfo2 *pCreateInfo,
92                                    const VkAllocationCallbacks *pAllocator, VkRenderPass *pRenderPass) const       = 0;
93     virtual void createPipelineLayout(VkDevice device, const VkPipelineLayoutCreateInfo *pCreateInfo,
94                                       const VkAllocationCallbacks *pAllocator,
95                                       VkPipelineLayout *pPipelineLayout) const                                     = 0;
96     virtual void createDescriptorSetLayout(VkDevice device, const VkDescriptorSetLayoutCreateInfo *pCreateInfo,
97                                            const VkAllocationCallbacks *pAllocator,
98                                            VkDescriptorSetLayout *pSetLayout) const                                = 0;
99     virtual void createSampler(VkDevice device, const VkSamplerCreateInfo *pCreateInfo,
100                                const VkAllocationCallbacks *pAllocator, VkSampler *pSampler) const                 = 0;
101     virtual void createSamplerYcbcrConversion(VkDevice device, const VkSamplerYcbcrConversionCreateInfo *pCreateInfo,
102                                               const VkAllocationCallbacks *pAllocator,
103                                               VkSamplerYcbcrConversion *pYcbcrConversion) const                    = 0;
104     virtual void createCommandPool(VkDevice device, const VkCommandPoolCreateInfo *pCreateInfo,
105                                    const VkAllocationCallbacks *pAllocator, VkCommandPool *pCommandPool) const     = 0;
106     virtual void allocateCommandBuffers(VkDevice device, const VkCommandBufferAllocateInfo *pAllocateInfo,
107                                         VkCommandBuffer *pCommandBuffers) const                                    = 0;
108     virtual void increaseCommandBufferSize(VkCommandBuffer commandBuffer, VkDeviceSize commandSize) const          = 0;
109     virtual void resetCommandPool(VkDevice device, VkCommandPool commandPool, VkCommandPoolResetFlags flags) const = 0;
110 
111     void removeRedundantObjects();
112     void finalizeCommandBuffers();
113     std::vector<uint8_t> exportData() const;
114     void importData(std::vector<uint8_t> &importText) const;
115     virtual void importPipelineCacheData(const PlatformInterface &vkp, VkInstance instance,
116                                          const InstanceInterface &vki, VkPhysicalDevice physicalDevice,
117                                          uint32_t queueIndex) = 0;
118     void registerObjectHash(uint64_t handle, std::size_t hashValue) const;
119     const std::map<uint64_t, std::size_t> &getObjectHashes() const;
120 
121     void preparePipelinePoolSizes();
122     std::vector<VkPipelinePoolSize> getPipelinePoolSizes() const;
123     void fillPoolEntrySize(vk::VkPipelineOfflineCreateInfo &pipelineIdentifier) const;
124     vksc_server::VulkanCommandMemoryConsumption getNextCommandPoolSize();
125     std::size_t getCacheDataSize() const;
126     const uint8_t *getCacheData() const;
127     VkPipelineCache getPipelineCache(VkDevice device) const;
128     virtual void resetObjects()        = 0;
129     virtual void resetPipelineCaches() = 0;
130 #endif // CTS_USES_VULKANSC
131 
132 protected:
133     virtual vk::ProgramBinary *compileProgram(const vk::ProgramIdentifier &progId, const vk::GlslSource &source,
134                                               glu::ShaderProgramInfo *buildInfo,
135                                               const tcu::CommandLine &commandLine)                                  = 0;
136     virtual vk::ProgramBinary *compileProgram(const vk::ProgramIdentifier &progId, const vk::HlslSource &source,
137                                               glu::ShaderProgramInfo *buildInfo,
138                                               const tcu::CommandLine &commandLine)                                  = 0;
139     virtual vk::ProgramBinary *compileProgram(const vk::ProgramIdentifier &progId, const vk::SpirVAsmSource &source,
140                                               vk::SpirVProgramInfo *buildInfo, const tcu::CommandLine &commandLine) = 0;
141 
142     tcu::TestContext &m_testCtx;
143     std::string m_currentTestPath;
144 
145 #ifdef CTS_USES_VULKANSC
146     mutable vksc_server::VulkanPipelineCacheInput m_pipelineInput;
147     mutable std::map<uint64_t, std::size_t> m_objectHashes;
148     mutable std::vector<vksc_server::VulkanCommandMemoryConsumption> m_commandPoolMemoryConsumption;
149     mutable uint32_t m_commandPoolIndex;
150     mutable std::map<VkCommandBuffer, vksc_server::VulkanCommandMemoryConsumption> m_commandBufferMemoryConsumption;
151     mutable std::map<VkDevice, std::string> m_deviceFeatures;
152     mutable std::map<VkDevice, std::vector<std::string>> m_deviceExtensions;
153 
154     std::map<VkDevice, de::SharedPtr<Move<VkPipelineCache>>> m_pipelineCache;
155 
156     mutable std::mutex m_mutex;
157     mutable uint64_t m_resourceCounter;
158     mutable VkDeviceObjectReservationCreateInfo m_statCurrent;
159     mutable VkDeviceObjectReservationCreateInfo m_statMax;
160 
161     std::vector<uint8_t> m_cacheData;
162     mutable std::map<VkPipeline, VkPipelineOfflineCreateInfo> m_pipelineIdentifiers;
163     mutable std::vector<vksc_server::VulkanPipelineSize> m_pipelineSizes;
164     std::vector<VkPipelinePoolSize> m_pipelinePoolSizes;
165     tcu::Maybe<uint32_t> m_version;
166     tcu::Maybe<bool> m_vulkanSC;
167     bool m_enabledHandleDestroy;
168 #endif // CTS_USES_VULKANSC
169 };
170 
171 typedef VKAPI_ATTR VkResult(VKAPI_CALL *CreateSamplerYcbcrConversionFunc)(
172     VkDevice device, const VkSamplerYcbcrConversionCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator,
173     VkSamplerYcbcrConversion *pYcbcrConversion);
174 typedef VKAPI_ATTR void(VKAPI_CALL *DestroySamplerYcbcrConversionFunc)(VkDevice device,
175                                                                        VkSamplerYcbcrConversion ycbcrConversion,
176                                                                        const VkAllocationCallbacks *pAllocator);
177 typedef VKAPI_ATTR VkResult(VKAPI_CALL *CreateSamplerFunc)(VkDevice device, const VkSamplerCreateInfo *pCreateInfo,
178                                                            const VkAllocationCallbacks *pAllocator,
179                                                            VkSampler *pSampler);
180 typedef VKAPI_ATTR void(VKAPI_CALL *DestroySamplerFunc)(VkDevice device, VkSampler sampler,
181                                                         const VkAllocationCallbacks *pAllocator);
182 typedef VKAPI_ATTR VkResult(VKAPI_CALL *CreateShaderModuleFunc)(VkDevice device,
183                                                                 const VkShaderModuleCreateInfo *pCreateInfo,
184                                                                 const VkAllocationCallbacks *pAllocator,
185                                                                 VkShaderModule *pShaderModule);
186 typedef VKAPI_ATTR void(VKAPI_CALL *DestroyShaderModuleFunc)(VkDevice device, VkShaderModule shaderModule,
187                                                              const VkAllocationCallbacks *pAllocator);
188 typedef VKAPI_ATTR VkResult(VKAPI_CALL *CreateRenderPassFunc)(VkDevice device,
189                                                               const VkRenderPassCreateInfo *pCreateInfo,
190                                                               const VkAllocationCallbacks *pAllocator,
191                                                               VkRenderPass *pRenderPass);
192 typedef VKAPI_ATTR VkResult(VKAPI_CALL *CreateRenderPass2Func)(VkDevice device,
193                                                                const VkRenderPassCreateInfo2 *pCreateInfo,
194                                                                const VkAllocationCallbacks *pAllocator,
195                                                                VkRenderPass *pRenderPass);
196 typedef VKAPI_ATTR void(VKAPI_CALL *DestroyRenderPassFunc)(VkDevice device, VkRenderPass renderPass,
197                                                            const VkAllocationCallbacks *pAllocator);
198 typedef VKAPI_ATTR VkResult(VKAPI_CALL *CreateDescriptorSetLayoutFunc)(
199     VkDevice device, const VkDescriptorSetLayoutCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator,
200     VkDescriptorSetLayout *pSetLayout);
201 typedef VKAPI_ATTR void(VKAPI_CALL *DestroyDescriptorSetLayoutFunc)(VkDevice device,
202                                                                     VkDescriptorSetLayout descriptorSetLayout,
203                                                                     const VkAllocationCallbacks *pAllocator);
204 typedef VKAPI_ATTR VkResult(VKAPI_CALL *CreatePipelineLayoutFunc)(VkDevice device,
205                                                                   const VkPipelineLayoutCreateInfo *pCreateInfo,
206                                                                   const VkAllocationCallbacks *pAllocator,
207                                                                   VkPipelineLayout *pPipelineLayout);
208 typedef VKAPI_ATTR void(VKAPI_CALL *DestroyPipelineLayoutFunc)(VkDevice device, VkPipelineLayout pipelineLayout,
209                                                                const VkAllocationCallbacks *pAllocator);
210 typedef VKAPI_ATTR VkResult(VKAPI_CALL *CreateGraphicsPipelinesFunc)(VkDevice device, VkPipelineCache pipelineCache,
211                                                                      uint32_t createInfoCount,
212                                                                      const VkGraphicsPipelineCreateInfo *pCreateInfos,
213                                                                      const VkAllocationCallbacks *pAllocator,
214                                                                      VkPipeline *pPipelines);
215 typedef VKAPI_ATTR VkResult(VKAPI_CALL *CreateComputePipelinesFunc)(VkDevice device, VkPipelineCache pipelineCache,
216                                                                     uint32_t createInfoCount,
217                                                                     const VkComputePipelineCreateInfo *pCreateInfos,
218                                                                     const VkAllocationCallbacks *pAllocator,
219                                                                     VkPipeline *pPipelines);
220 typedef VKAPI_ATTR void(VKAPI_CALL *DestroyPipelineFunc)(VkDevice device, VkPipeline pipeline,
221                                                          const VkAllocationCallbacks *pAllocator);
222 typedef VKAPI_ATTR VkResult(VKAPI_CALL *CreatePipelineCacheFunc)(VkDevice device,
223                                                                  const VkPipelineCacheCreateInfo *pCreateInfo,
224                                                                  const VkAllocationCallbacks *pAllocator,
225                                                                  VkPipelineCache *pPipelineCache);
226 typedef VKAPI_ATTR void(VKAPI_CALL *DestroyPipelineCacheFunc)(VkDevice device, VkPipelineCache pipelineCache,
227                                                               const VkAllocationCallbacks *pAllocator);
228 typedef VKAPI_ATTR VkResult(VKAPI_CALL *GetPipelineCacheDataFunc)(VkDevice device, VkPipelineCache pipelineCache,
229                                                                   uintptr_t *pDataSize, void *pData);
230 #ifdef CTS_USES_VULKANSC
231 typedef VKAPI_ATTR void(VKAPI_CALL *GetCommandPoolMemoryConsumptionFunc)(VkDevice device, VkCommandPool commandPool,
232                                                                          VkCommandBuffer commandBuffer,
233                                                                          VkCommandPoolMemoryConsumption *pConsumption);
234 #endif // CTS_USES_VULKANSC
235 
236 class ResourceInterfaceStandard : public ResourceInterface
237 {
238 public:
239     ResourceInterfaceStandard(tcu::TestContext &testCtx);
240 
241     void initDevice(DeviceInterface &deviceInterface, VkDevice device) override;
242     void deinitDevice(VkDevice device) override;
243 
244 #ifdef CTS_USES_VULKANSC
245     void registerDeviceFeatures(VkDevice device, const VkDeviceCreateInfo *pCreateInfo) const override;
246     void unregisterDeviceFeatures(VkDevice device) const override;
247     VkResult createShaderModule(VkDevice device, const VkShaderModuleCreateInfo *pCreateInfo,
248                                 const VkAllocationCallbacks *pAllocator, VkShaderModule *pShaderModule,
249                                 bool normalMode) const override;
250     VkResult createGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount,
251                                      const VkGraphicsPipelineCreateInfo *pCreateInfos,
252                                      const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
253                                      bool normalMode) const override;
254     VkResult createComputePipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount,
255                                     const VkComputePipelineCreateInfo *pCreateInfos,
256                                     const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
257                                     bool normalMode) const override;
258     void destroyPipeline(VkDevice device, VkPipeline pipeline, const VkAllocationCallbacks *pAllocator) const override;
259     void createRenderPass(VkDevice device, const VkRenderPassCreateInfo *pCreateInfo,
260                           const VkAllocationCallbacks *pAllocator, VkRenderPass *pRenderPass) const override;
261     void createRenderPass2(VkDevice device, const VkRenderPassCreateInfo2 *pCreateInfo,
262                            const VkAllocationCallbacks *pAllocator, VkRenderPass *pRenderPass) const override;
263     void createPipelineLayout(VkDevice device, const VkPipelineLayoutCreateInfo *pCreateInfo,
264                               const VkAllocationCallbacks *pAllocator,
265                               VkPipelineLayout *pPipelineLayout) const override;
266     void createDescriptorSetLayout(VkDevice device, const VkDescriptorSetLayoutCreateInfo *pCreateInfo,
267                                    const VkAllocationCallbacks *pAllocator,
268                                    VkDescriptorSetLayout *pSetLayout) const override;
269     void createSampler(VkDevice device, const VkSamplerCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator,
270                        VkSampler *pSampler) const override;
271     void createSamplerYcbcrConversion(VkDevice device, const VkSamplerYcbcrConversionCreateInfo *pCreateInfo,
272                                       const VkAllocationCallbacks *pAllocator,
273                                       VkSamplerYcbcrConversion *pYcbcrConversion) const override;
274     void createCommandPool(VkDevice device, const VkCommandPoolCreateInfo *pCreateInfo,
275                            const VkAllocationCallbacks *pAllocator, VkCommandPool *pCommandPool) const override;
276     void allocateCommandBuffers(VkDevice device, const VkCommandBufferAllocateInfo *pAllocateInfo,
277                                 VkCommandBuffer *pCommandBuffers) const override;
278     void increaseCommandBufferSize(VkCommandBuffer commandBuffer, VkDeviceSize commandSize) const override;
279     void resetCommandPool(VkDevice device, VkCommandPool commandPool, VkCommandPoolResetFlags flags) const override;
280     void importPipelineCacheData(const PlatformInterface &vkp, VkInstance instance, const InstanceInterface &vki,
281                                  VkPhysicalDevice physicalDevice, uint32_t queueIndex) override;
282     void resetObjects() override;
283     void resetPipelineCaches() override;
284 #endif // CTS_USES_VULKANSC
285 
286 protected:
287     vk::ProgramBinary *compileProgram(const vk::ProgramIdentifier &progId, const vk::GlslSource &source,
288                                       glu::ShaderProgramInfo *buildInfo, const tcu::CommandLine &commandLine) override;
289     vk::ProgramBinary *compileProgram(const vk::ProgramIdentifier &progId, const vk::HlslSource &source,
290                                       glu::ShaderProgramInfo *buildInfo, const tcu::CommandLine &commandLine) override;
291     vk::ProgramBinary *compileProgram(const vk::ProgramIdentifier &progId, const vk::SpirVAsmSource &source,
292                                       vk::SpirVProgramInfo *buildInfo, const tcu::CommandLine &commandLine) override;
293 
294     std::map<VkDevice, CreateShaderModuleFunc> m_createShaderModuleFunc;
295     std::map<VkDevice, CreateGraphicsPipelinesFunc> m_createGraphicsPipelinesFunc;
296     std::map<VkDevice, CreateComputePipelinesFunc> m_createComputePipelinesFunc;
297 };
298 
299 #ifdef CTS_USES_VULKANSC
300 
301 class ResourceInterfaceVKSC : public ResourceInterfaceStandard
302 {
303 public:
304     ResourceInterfaceVKSC(tcu::TestContext &testCtx);
305 
306     VkResult createShaderModule(VkDevice device, const VkShaderModuleCreateInfo *pCreateInfo,
307                                 const VkAllocationCallbacks *pAllocator, VkShaderModule *pShaderModule,
308                                 bool normalMode) const override;
309 
310     void importPipelineCacheData(const PlatformInterface &vkp, VkInstance instance, const InstanceInterface &vki,
311                                  VkPhysicalDevice physicalDevice, uint32_t queueIndex) override;
312 
313 protected:
314     vk::ProgramBinary *compileProgram(const vk::ProgramIdentifier &progId, const vk::GlslSource &source,
315                                       glu::ShaderProgramInfo *buildInfo, const tcu::CommandLine &commandLine) override;
316     vk::ProgramBinary *compileProgram(const vk::ProgramIdentifier &progId, const vk::HlslSource &source,
317                                       glu::ShaderProgramInfo *buildInfo, const tcu::CommandLine &commandLine) override;
318     vk::ProgramBinary *compileProgram(const vk::ProgramIdentifier &progId, const vk::SpirVAsmSource &source,
319                                       vk::SpirVProgramInfo *buildInfo, const tcu::CommandLine &commandLine) override;
320 
321 private:
322     vksc_server::Server *getServer();
323     bool noServer() const;
324 
325     std::string m_address;
326     std::shared_ptr<vksc_server::Server> m_server;
327 };
328 
329 class MultithreadedDestroyGuard
330 {
331 public:
332     MultithreadedDestroyGuard(de::SharedPtr<vk::ResourceInterface> resourceInterface);
333     ~MultithreadedDestroyGuard();
334 
335 private:
336     de::SharedPtr<vk::ResourceInterface> m_resourceInterface;
337 };
338 
339 #endif // CTS_USES_VULKANSC
340 
341 template <typename InfoType, typename IteratorType>
buildProgram(const std::string & casePath,IteratorType iter,const vk::BinaryRegistryReader & prebuiltBinRegistry,vk::BinaryCollection * progCollection)342 vk::ProgramBinary *ResourceInterface::buildProgram(const std::string &casePath, IteratorType iter,
343                                                    const vk::BinaryRegistryReader &prebuiltBinRegistry,
344                                                    vk::BinaryCollection *progCollection)
345 {
346     const vk::ProgramIdentifier progId(casePath, iter.getName());
347     tcu::TestLog &log                   = m_testCtx.getLog();
348     const tcu::CommandLine &commandLine = m_testCtx.getCommandLine();
349     const tcu::ScopedLogSection progSection(log, iter.getName(), "Program: " + iter.getName());
350     de::MovePtr<vk::ProgramBinary> binProg;
351     InfoType buildInfo;
352 
353     try
354     {
355         binProg = de::MovePtr<vk::ProgramBinary>(compileProgram(progId, iter.getProgram(), &buildInfo, commandLine));
356         log << buildInfo;
357     }
358     catch (const tcu::NotSupportedError &err)
359     {
360         // Try to load from cache
361         log << err << tcu::TestLog::Message << "Building from source not supported, loading stored binary instead"
362             << tcu::TestLog::EndMessage;
363 
364         binProg = de::MovePtr<vk::ProgramBinary>(prebuiltBinRegistry.loadProgram(progId));
365 
366         log << iter.getProgram();
367     }
368     catch (const tcu::Exception &)
369     {
370         // Build failed for other reason
371         log << buildInfo;
372         throw;
373     }
374 
375     TCU_CHECK_INTERNAL(binProg);
376 
377     {
378         vk::ProgramBinary *const returnBinary = binProg.get();
379 
380         progCollection->add(progId.programName, binProg);
381 
382         return returnBinary;
383     }
384 }
385 
386 } // namespace vk
387 
388 #endif // _VKRESOURCEINTERFACE_HPP
389