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,
50 VkDevice device) = 0;
51 // use deinitDevice when your DeviceDriverSC is created and removed inside TestInstance
52 virtual void deinitDevice (VkDevice device) = 0;
53
54 virtual void initTestCase (const std::string& casePath);
55 const std::string& getCasePath () const;
56
57 // buildProgram
58 template <typename InfoType, typename IteratorType>
59 vk::ProgramBinary* buildProgram (const std::string& casePath,
60 IteratorType iter,
61 const vk::BinaryRegistryReader& prebuiltBinRegistry,
62 vk::BinaryCollection* progCollection);
63
64 #ifdef CTS_USES_VULKANSC
65 void initApiVersion (const deUint32 version);
66 bool isVulkanSC (void) const;
67
68 deUint64 incResourceCounter ();
69 std::mutex& getStatMutex ();
70 VkDeviceObjectReservationCreateInfo& getStatCurrent ();
71 VkDeviceObjectReservationCreateInfo& getStatMax ();
72 const VkDeviceObjectReservationCreateInfo& getStatMax () const;
73 void setHandleDestroy (bool value);
74 bool isEnabledHandleDestroy () const;
75
76 virtual void registerDeviceFeatures (VkDevice device,
77 const VkDeviceCreateInfo* pCreateInfo) const = 0;
78 virtual void unregisterDeviceFeatures (VkDevice device) const = 0;
79 virtual VkResult createShaderModule (VkDevice device,
80 const VkShaderModuleCreateInfo* pCreateInfo,
81 const VkAllocationCallbacks* pAllocator,
82 VkShaderModule* pShaderModule,
83 bool normalMode) const = 0;
84 virtual VkResult createGraphicsPipelines (VkDevice device,
85 VkPipelineCache pipelineCache,
86 deUint32 createInfoCount,
87 const VkGraphicsPipelineCreateInfo* pCreateInfos,
88 const VkAllocationCallbacks* pAllocator,
89 VkPipeline* pPipelines,
90 bool normalMode) const = 0;
91 virtual VkResult createComputePipelines (VkDevice device,
92 VkPipelineCache pipelineCache,
93 deUint32 createInfoCount,
94 const VkComputePipelineCreateInfo* pCreateInfos,
95 const VkAllocationCallbacks* pAllocator,
96 VkPipeline* pPipelines,
97 bool normalMode) const = 0;
98 virtual void destroyPipeline (VkDevice device,
99 VkPipeline pipeline,
100 const VkAllocationCallbacks* pAllocator) const = 0;
101 virtual void createRenderPass (VkDevice device,
102 const VkRenderPassCreateInfo* pCreateInfo,
103 const VkAllocationCallbacks* pAllocator,
104 VkRenderPass* pRenderPass) const = 0;
105 virtual void createRenderPass2 (VkDevice device,
106 const VkRenderPassCreateInfo2* pCreateInfo,
107 const VkAllocationCallbacks* pAllocator,
108 VkRenderPass* pRenderPass) const = 0;
109 virtual void createPipelineLayout (VkDevice device,
110 const VkPipelineLayoutCreateInfo* pCreateInfo,
111 const VkAllocationCallbacks* pAllocator,
112 VkPipelineLayout* pPipelineLayout) const = 0;
113 virtual void createDescriptorSetLayout (VkDevice device,
114 const VkDescriptorSetLayoutCreateInfo* pCreateInfo,
115 const VkAllocationCallbacks* pAllocator,
116 VkDescriptorSetLayout* pSetLayout) const = 0;
117 virtual void createSampler (VkDevice device,
118 const VkSamplerCreateInfo* pCreateInfo,
119 const VkAllocationCallbacks* pAllocator,
120 VkSampler* pSampler) const = 0;
121 virtual void createSamplerYcbcrConversion(VkDevice device,
122 const VkSamplerYcbcrConversionCreateInfo* pCreateInfo,
123 const VkAllocationCallbacks* pAllocator,
124 VkSamplerYcbcrConversion* pYcbcrConversion) const = 0;
125 virtual void createCommandPool (VkDevice device,
126 const VkCommandPoolCreateInfo* pCreateInfo,
127 const VkAllocationCallbacks* pAllocator,
128 VkCommandPool* pCommandPool) const = 0;
129 virtual void allocateCommandBuffers (VkDevice device,
130 const VkCommandBufferAllocateInfo* pAllocateInfo,
131 VkCommandBuffer* pCommandBuffers) const = 0;
132 virtual void increaseCommandBufferSize (VkCommandBuffer commandBuffer,
133 VkDeviceSize commandSize) const = 0;
134 virtual void resetCommandPool (VkDevice device,
135 VkCommandPool commandPool,
136 VkCommandPoolResetFlags flags) const = 0;
137
138 void removeRedundantObjects ();
139 void finalizeCommandBuffers ();
140 std::vector<deUint8> exportData () const;
141 void importData (std::vector<deUint8>& importText) const;
142 virtual void importPipelineCacheData (const PlatformInterface& vkp,
143 VkInstance instance,
144 const InstanceInterface& vki,
145 VkPhysicalDevice physicalDevice,
146 deUint32 queueIndex) = 0;
147 void registerObjectHash (deUint64 handle,
148 std::size_t hashValue) const;
149 const std::map<deUint64, std::size_t>& getObjectHashes () const;
150
151 void preparePipelinePoolSizes ();
152 std::vector<VkPipelinePoolSize> getPipelinePoolSizes () const;
153 void fillPoolEntrySize (vk::VkPipelineOfflineCreateInfo& pipelineIdentifier) const;
154 vksc_server::VulkanCommandMemoryConsumption getNextCommandPoolSize ();
155 std::size_t getCacheDataSize () const;
156 const deUint8* getCacheData () const;
157 VkPipelineCache getPipelineCache (VkDevice device) const;
158 virtual void resetObjects () = 0;
159 virtual void resetPipelineCaches () = 0;
160 #endif // CTS_USES_VULKANSC
161
162 protected:
163 virtual vk::ProgramBinary* compileProgram (const vk::ProgramIdentifier& progId,
164 const vk::GlslSource& source,
165 glu::ShaderProgramInfo* buildInfo,
166 const tcu::CommandLine& commandLine) = 0;
167 virtual vk::ProgramBinary* compileProgram (const vk::ProgramIdentifier& progId,
168 const vk::HlslSource& source,
169 glu::ShaderProgramInfo* buildInfo,
170 const tcu::CommandLine& commandLine) = 0;
171 virtual vk::ProgramBinary* compileProgram (const vk::ProgramIdentifier& progId,
172 const vk::SpirVAsmSource& source,
173 vk::SpirVProgramInfo* buildInfo,
174 const tcu::CommandLine& commandLine) = 0;
175
176 tcu::TestContext& m_testCtx;
177 std::string m_currentTestPath;
178
179 #ifdef CTS_USES_VULKANSC
180 mutable vksc_server::VulkanPipelineCacheInput m_pipelineInput;
181 mutable std::map<deUint64, std::size_t> m_objectHashes;
182 mutable std::vector<vksc_server::VulkanCommandMemoryConsumption>
183 m_commandPoolMemoryConsumption;
184 mutable deUint32 m_commandPoolIndex;
185 mutable std::map<VkCommandBuffer, vksc_server::VulkanCommandMemoryConsumption>
186 m_commandBufferMemoryConsumption;
187 mutable std::map<VkDevice, std::string> m_deviceFeatures;
188 mutable std::map<VkDevice, std::vector<std::string>> m_deviceExtensions;
189
190 std::map<VkDevice,de::SharedPtr<Move<VkPipelineCache>>> m_pipelineCache;
191
192 mutable std::mutex m_mutex;
193 mutable deUint64 m_resourceCounter;
194 mutable VkDeviceObjectReservationCreateInfo m_statCurrent;
195 mutable VkDeviceObjectReservationCreateInfo m_statMax;
196
197 std::vector<deUint8> m_cacheData;
198 mutable std::map<VkPipeline, VkPipelineOfflineCreateInfo> m_pipelineIdentifiers;
199 mutable std::vector<vksc_server::VulkanPipelineSize> m_pipelineSizes;
200 std::vector<VkPipelinePoolSize> m_pipelinePoolSizes;
201 tcu::Maybe<deUint32> m_version;
202 tcu::Maybe<bool> m_vulkanSC;
203 bool m_enabledHandleDestroy;
204 #endif // CTS_USES_VULKANSC
205 };
206
207 typedef VKAPI_ATTR VkResult (VKAPI_CALL* CreateSamplerYcbcrConversionFunc) (VkDevice device, const VkSamplerYcbcrConversionCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSamplerYcbcrConversion* pYcbcrConversion);
208 typedef VKAPI_ATTR void (VKAPI_CALL* DestroySamplerYcbcrConversionFunc) (VkDevice device, VkSamplerYcbcrConversion ycbcrConversion, const VkAllocationCallbacks* pAllocator);
209 typedef VKAPI_ATTR VkResult (VKAPI_CALL* CreateSamplerFunc) (VkDevice device, const VkSamplerCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSampler* pSampler);
210 typedef VKAPI_ATTR void (VKAPI_CALL* DestroySamplerFunc) (VkDevice device, VkSampler sampler, const VkAllocationCallbacks* pAllocator);
211 typedef VKAPI_ATTR VkResult (VKAPI_CALL* CreateShaderModuleFunc) (VkDevice device, const VkShaderModuleCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkShaderModule* pShaderModule);
212 typedef VKAPI_ATTR void (VKAPI_CALL* DestroyShaderModuleFunc) (VkDevice device, VkShaderModule shaderModule, const VkAllocationCallbacks* pAllocator);
213 typedef VKAPI_ATTR VkResult (VKAPI_CALL* CreateRenderPassFunc) (VkDevice device, const VkRenderPassCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkRenderPass* pRenderPass);
214 typedef VKAPI_ATTR VkResult (VKAPI_CALL* CreateRenderPass2Func) (VkDevice device, const VkRenderPassCreateInfo2* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkRenderPass* pRenderPass);
215 typedef VKAPI_ATTR void (VKAPI_CALL* DestroyRenderPassFunc) (VkDevice device, VkRenderPass renderPass, const VkAllocationCallbacks* pAllocator);
216 typedef VKAPI_ATTR VkResult (VKAPI_CALL* CreateDescriptorSetLayoutFunc) (VkDevice device, const VkDescriptorSetLayoutCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDescriptorSetLayout* pSetLayout);
217 typedef VKAPI_ATTR void (VKAPI_CALL* DestroyDescriptorSetLayoutFunc) (VkDevice device, VkDescriptorSetLayout descriptorSetLayout, const VkAllocationCallbacks* pAllocator);
218 typedef VKAPI_ATTR VkResult (VKAPI_CALL* CreatePipelineLayoutFunc) (VkDevice device, const VkPipelineLayoutCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkPipelineLayout* pPipelineLayout);
219 typedef VKAPI_ATTR void (VKAPI_CALL* DestroyPipelineLayoutFunc) (VkDevice device, VkPipelineLayout pipelineLayout, const VkAllocationCallbacks* pAllocator);
220 typedef VKAPI_ATTR VkResult (VKAPI_CALL* CreateGraphicsPipelinesFunc) (VkDevice device, VkPipelineCache pipelineCache, deUint32 createInfoCount, const VkGraphicsPipelineCreateInfo* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines);
221 typedef VKAPI_ATTR VkResult (VKAPI_CALL* CreateComputePipelinesFunc) (VkDevice device, VkPipelineCache pipelineCache, deUint32 createInfoCount, const VkComputePipelineCreateInfo* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines);
222 typedef VKAPI_ATTR void (VKAPI_CALL* DestroyPipelineFunc) (VkDevice device, VkPipeline pipeline, const VkAllocationCallbacks* pAllocator);
223 typedef VKAPI_ATTR VkResult (VKAPI_CALL* CreatePipelineCacheFunc) (VkDevice device, const VkPipelineCacheCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkPipelineCache* pPipelineCache);
224 typedef VKAPI_ATTR void (VKAPI_CALL* DestroyPipelineCacheFunc) (VkDevice device, VkPipelineCache pipelineCache, const VkAllocationCallbacks* pAllocator);
225 typedef VKAPI_ATTR VkResult (VKAPI_CALL* GetPipelineCacheDataFunc) (VkDevice device, VkPipelineCache pipelineCache, deUintptr* pDataSize, void* pData);
226 #ifdef CTS_USES_VULKANSC
227 typedef VKAPI_ATTR void (VKAPI_CALL* GetCommandPoolMemoryConsumptionFunc) (VkDevice device, VkCommandPool commandPool, VkCommandBuffer commandBuffer, VkCommandPoolMemoryConsumption* pConsumption);
228 #endif // CTS_USES_VULKANSC
229
230 class ResourceInterfaceStandard : public ResourceInterface
231 {
232 public:
233 ResourceInterfaceStandard (tcu::TestContext& testCtx);
234
235 void initDevice (DeviceInterface& deviceInterface,
236 VkDevice device) override;
237 void deinitDevice (VkDevice device) override;
238
239 #ifdef CTS_USES_VULKANSC
240 void registerDeviceFeatures (VkDevice device,
241 const VkDeviceCreateInfo* pCreateInfo) const override;
242 void unregisterDeviceFeatures (VkDevice device) const override;
243 VkResult createShaderModule (VkDevice device,
244 const VkShaderModuleCreateInfo* pCreateInfo,
245 const VkAllocationCallbacks* pAllocator,
246 VkShaderModule* pShaderModule,
247 bool normalMode) const override;
248 VkResult createGraphicsPipelines (VkDevice device,
249 VkPipelineCache pipelineCache,
250 deUint32 createInfoCount,
251 const VkGraphicsPipelineCreateInfo* pCreateInfos,
252 const VkAllocationCallbacks* pAllocator,
253 VkPipeline* pPipelines,
254 bool normalMode) const override;
255 VkResult createComputePipelines (VkDevice device,
256 VkPipelineCache pipelineCache,
257 deUint32 createInfoCount,
258 const VkComputePipelineCreateInfo* pCreateInfos,
259 const VkAllocationCallbacks* pAllocator,
260 VkPipeline* pPipelines,
261 bool normalMode) const override;
262 void destroyPipeline (VkDevice device,
263 VkPipeline pipeline,
264 const VkAllocationCallbacks* pAllocator) const override;
265 void createRenderPass (VkDevice device,
266 const VkRenderPassCreateInfo* pCreateInfo,
267 const VkAllocationCallbacks* pAllocator,
268 VkRenderPass* pRenderPass) const override;
269 void createRenderPass2 (VkDevice device,
270 const VkRenderPassCreateInfo2* pCreateInfo,
271 const VkAllocationCallbacks* pAllocator,
272 VkRenderPass* pRenderPass) const override;
273 void createPipelineLayout (VkDevice device,
274 const VkPipelineLayoutCreateInfo* pCreateInfo,
275 const VkAllocationCallbacks* pAllocator,
276 VkPipelineLayout* pPipelineLayout) const override;
277 void createDescriptorSetLayout (VkDevice device,
278 const VkDescriptorSetLayoutCreateInfo* pCreateInfo,
279 const VkAllocationCallbacks* pAllocator,
280 VkDescriptorSetLayout* pSetLayout) const override;
281 void createSampler (VkDevice device,
282 const VkSamplerCreateInfo* pCreateInfo,
283 const VkAllocationCallbacks* pAllocator,
284 VkSampler* pSampler) const override;
285 void createSamplerYcbcrConversion(VkDevice device,
286 const VkSamplerYcbcrConversionCreateInfo* pCreateInfo,
287 const VkAllocationCallbacks* pAllocator,
288 VkSamplerYcbcrConversion* pYcbcrConversion) const override;
289 void createCommandPool (VkDevice device,
290 const VkCommandPoolCreateInfo* pCreateInfo,
291 const VkAllocationCallbacks* pAllocator,
292 VkCommandPool* pCommandPool) const override;
293 void allocateCommandBuffers (VkDevice device,
294 const VkCommandBufferAllocateInfo* pAllocateInfo,
295 VkCommandBuffer* pCommandBuffers) const override;
296 void increaseCommandBufferSize (VkCommandBuffer commandBuffer,
297 VkDeviceSize commandSize) const override;
298 void resetCommandPool (VkDevice device,
299 VkCommandPool commandPool,
300 VkCommandPoolResetFlags flags) const override;
301 void importPipelineCacheData (const PlatformInterface& vkp,
302 VkInstance instance,
303 const InstanceInterface& vki,
304 VkPhysicalDevice physicalDevice,
305 deUint32 queueIndex) override;
306 void resetObjects () override;
307 void resetPipelineCaches () override;
308 #endif // CTS_USES_VULKANSC
309
310 protected:
311 vk::ProgramBinary* compileProgram (const vk::ProgramIdentifier& progId,
312 const vk::GlslSource& source,
313 glu::ShaderProgramInfo* buildInfo,
314 const tcu::CommandLine& commandLine) override;
315 vk::ProgramBinary* compileProgram (const vk::ProgramIdentifier& progId,
316 const vk::HlslSource& source,
317 glu::ShaderProgramInfo* buildInfo,
318 const tcu::CommandLine& commandLine) override;
319 vk::ProgramBinary* compileProgram (const vk::ProgramIdentifier& progId,
320 const vk::SpirVAsmSource& source,
321 vk::SpirVProgramInfo* buildInfo,
322 const tcu::CommandLine& commandLine) override;
323
324 std::map<VkDevice,CreateShaderModuleFunc> m_createShaderModuleFunc;
325 std::map<VkDevice,CreateGraphicsPipelinesFunc> m_createGraphicsPipelinesFunc;
326 std::map<VkDevice,CreateComputePipelinesFunc> m_createComputePipelinesFunc;
327 };
328
329 #ifdef CTS_USES_VULKANSC
330
331 class ResourceInterfaceVKSC : public ResourceInterfaceStandard
332 {
333 public:
334 ResourceInterfaceVKSC (tcu::TestContext& testCtx);
335
336 VkResult createShaderModule (VkDevice device,
337 const VkShaderModuleCreateInfo* pCreateInfo,
338 const VkAllocationCallbacks* pAllocator,
339 VkShaderModule* pShaderModule,
340 bool normalMode) const override;
341
342 void importPipelineCacheData (const PlatformInterface& vkp,
343 VkInstance instance,
344 const InstanceInterface& vki,
345 VkPhysicalDevice physicalDevice,
346 deUint32 queueIndex) override;
347
348 protected:
349 vk::ProgramBinary* compileProgram (const vk::ProgramIdentifier& progId,
350 const vk::GlslSource& source,
351 glu::ShaderProgramInfo* buildInfo,
352 const tcu::CommandLine& commandLine) override;
353 vk::ProgramBinary* compileProgram (const vk::ProgramIdentifier& progId,
354 const vk::HlslSource& source,
355 glu::ShaderProgramInfo* buildInfo,
356 const tcu::CommandLine& commandLine) override;
357 vk::ProgramBinary* compileProgram (const vk::ProgramIdentifier& progId,
358 const vk::SpirVAsmSource& source,
359 vk::SpirVProgramInfo* buildInfo,
360 const tcu::CommandLine& commandLine) override;
361
362 private:
363 vksc_server::Server* getServer ();
364 bool noServer () const;
365
366 std::string m_address;
367 std::shared_ptr<vksc_server::Server> m_server;
368 };
369
370 class MultithreadedDestroyGuard
371 {
372 public:
373 MultithreadedDestroyGuard (de::SharedPtr<vk::ResourceInterface> resourceInterface);
374 ~MultithreadedDestroyGuard ();
375 private:
376 de::SharedPtr<vk::ResourceInterface> m_resourceInterface;
377 };
378
379 #endif // CTS_USES_VULKANSC
380
381 template <typename InfoType, typename IteratorType>
buildProgram(const std::string & casePath,IteratorType iter,const vk::BinaryRegistryReader & prebuiltBinRegistry,vk::BinaryCollection * progCollection)382 vk::ProgramBinary* ResourceInterface::buildProgram (const std::string& casePath,
383 IteratorType iter,
384 const vk::BinaryRegistryReader& prebuiltBinRegistry,
385 vk::BinaryCollection* progCollection)
386 {
387 const vk::ProgramIdentifier progId (casePath, iter.getName());
388 tcu::TestLog& log = m_testCtx.getLog();
389 const tcu::CommandLine& commandLine = m_testCtx.getCommandLine();
390 const tcu::ScopedLogSection progSection (log, iter.getName(), "Program: " + iter.getName());
391 de::MovePtr<vk::ProgramBinary> binProg;
392 InfoType buildInfo;
393
394 try
395 {
396 binProg = de::MovePtr<vk::ProgramBinary>(compileProgram(progId, iter.getProgram(), &buildInfo, commandLine));
397 log << buildInfo;
398 }
399 catch (const tcu::NotSupportedError& err)
400 {
401 // Try to load from cache
402 log << err << tcu::TestLog::Message << "Building from source not supported, loading stored binary instead" << tcu::TestLog::EndMessage;
403
404 binProg = de::MovePtr<vk::ProgramBinary>(prebuiltBinRegistry.loadProgram(progId));
405
406 log << iter.getProgram();
407 }
408 catch (const tcu::Exception&)
409 {
410 // Build failed for other reason
411 log << buildInfo;
412 throw;
413 }
414
415 TCU_CHECK_INTERNAL(binProg);
416
417 {
418 vk::ProgramBinary* const returnBinary = binProg.get();
419
420 progCollection->add(progId.programName, binProg);
421
422 return returnBinary;
423 }
424 }
425
426 } // vk
427
428 #endif // _VKRESOURCEINTERFACE_HPP
429