xref: /aosp_15_r20/external/deqp/external/vulkancts/vkscserver/vksCacheBuilder.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1*35238bceSAndroid Build Coastguard Worker /*-------------------------------------------------------------------------
2*35238bceSAndroid Build Coastguard Worker  * Vulkan CTS Framework
3*35238bceSAndroid Build Coastguard Worker  * --------------------
4*35238bceSAndroid Build Coastguard Worker  *
5*35238bceSAndroid Build Coastguard Worker  * Copyright (c) 2021 The Khronos Group Inc.
6*35238bceSAndroid Build Coastguard Worker  *
7*35238bceSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
8*35238bceSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
9*35238bceSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
10*35238bceSAndroid Build Coastguard Worker  *
11*35238bceSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
12*35238bceSAndroid Build Coastguard Worker  *
13*35238bceSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
14*35238bceSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
15*35238bceSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16*35238bceSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
17*35238bceSAndroid Build Coastguard Worker  * limitations under the License.
18*35238bceSAndroid Build Coastguard Worker  *
19*35238bceSAndroid Build Coastguard Worker  *-------------------------------------------------------------------------*/
20*35238bceSAndroid Build Coastguard Worker 
21*35238bceSAndroid Build Coastguard Worker #include "vksCacheBuilder.hpp"
22*35238bceSAndroid Build Coastguard Worker #include "pcreader.hpp"
23*35238bceSAndroid Build Coastguard Worker #include "vksJson.hpp"
24*35238bceSAndroid Build Coastguard Worker 
25*35238bceSAndroid Build Coastguard Worker #include <fstream>
26*35238bceSAndroid Build Coastguard Worker //    Currently CTS does not use C++17, so universal method of deleting files from directory has been commented out
27*35238bceSAndroid Build Coastguard Worker //#include <filesystem>
28*35238bceSAndroid Build Coastguard Worker #include "vkRefUtil.hpp"
29*35238bceSAndroid Build Coastguard Worker #include "vkQueryUtil.hpp"
30*35238bceSAndroid Build Coastguard Worker #include "deDirectoryIterator.hpp"
31*35238bceSAndroid Build Coastguard Worker #include "deFile.h"
32*35238bceSAndroid Build Coastguard Worker #include "vkSafetyCriticalUtil.hpp"
33*35238bceSAndroid Build Coastguard Worker 
34*35238bceSAndroid Build Coastguard Worker namespace vk
35*35238bceSAndroid Build Coastguard Worker {
36*35238bceSAndroid Build Coastguard Worker 
37*35238bceSAndroid Build Coastguard Worker typedef VKAPI_ATTR VkResult(VKAPI_CALL *CreateSamplerYcbcrConversionFunc)(
38*35238bceSAndroid Build Coastguard Worker     VkDevice device, const VkSamplerYcbcrConversionCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator,
39*35238bceSAndroid Build Coastguard Worker     VkSamplerYcbcrConversion *pYcbcrConversion);
40*35238bceSAndroid Build Coastguard Worker typedef VKAPI_ATTR void(VKAPI_CALL *DestroySamplerYcbcrConversionFunc)(VkDevice device,
41*35238bceSAndroid Build Coastguard Worker                                                                        VkSamplerYcbcrConversion ycbcrConversion,
42*35238bceSAndroid Build Coastguard Worker                                                                        const VkAllocationCallbacks *pAllocator);
43*35238bceSAndroid Build Coastguard Worker typedef VKAPI_ATTR VkResult(VKAPI_CALL *CreateSamplerFunc)(VkDevice device, const VkSamplerCreateInfo *pCreateInfo,
44*35238bceSAndroid Build Coastguard Worker                                                            const VkAllocationCallbacks *pAllocator,
45*35238bceSAndroid Build Coastguard Worker                                                            VkSampler *pSampler);
46*35238bceSAndroid Build Coastguard Worker typedef VKAPI_ATTR void(VKAPI_CALL *DestroySamplerFunc)(VkDevice device, VkSampler sampler,
47*35238bceSAndroid Build Coastguard Worker                                                         const VkAllocationCallbacks *pAllocator);
48*35238bceSAndroid Build Coastguard Worker typedef VKAPI_ATTR VkResult(VKAPI_CALL *CreateShaderModuleFunc)(VkDevice device,
49*35238bceSAndroid Build Coastguard Worker                                                                 const VkShaderModuleCreateInfo *pCreateInfo,
50*35238bceSAndroid Build Coastguard Worker                                                                 const VkAllocationCallbacks *pAllocator,
51*35238bceSAndroid Build Coastguard Worker                                                                 VkShaderModule *pShaderModule);
52*35238bceSAndroid Build Coastguard Worker typedef VKAPI_ATTR void(VKAPI_CALL *DestroyShaderModuleFunc)(VkDevice device, VkShaderModule shaderModule,
53*35238bceSAndroid Build Coastguard Worker                                                              const VkAllocationCallbacks *pAllocator);
54*35238bceSAndroid Build Coastguard Worker typedef VKAPI_ATTR VkResult(VKAPI_CALL *CreateRenderPassFunc)(VkDevice device,
55*35238bceSAndroid Build Coastguard Worker                                                               const VkRenderPassCreateInfo *pCreateInfo,
56*35238bceSAndroid Build Coastguard Worker                                                               const VkAllocationCallbacks *pAllocator,
57*35238bceSAndroid Build Coastguard Worker                                                               VkRenderPass *pRenderPass);
58*35238bceSAndroid Build Coastguard Worker typedef VKAPI_ATTR VkResult(VKAPI_CALL *CreateRenderPass2Func)(VkDevice device,
59*35238bceSAndroid Build Coastguard Worker                                                                const VkRenderPassCreateInfo2 *pCreateInfo,
60*35238bceSAndroid Build Coastguard Worker                                                                const VkAllocationCallbacks *pAllocator,
61*35238bceSAndroid Build Coastguard Worker                                                                VkRenderPass *pRenderPass);
62*35238bceSAndroid Build Coastguard Worker typedef VKAPI_ATTR void(VKAPI_CALL *DestroyRenderPassFunc)(VkDevice device, VkRenderPass renderPass,
63*35238bceSAndroid Build Coastguard Worker                                                            const VkAllocationCallbacks *pAllocator);
64*35238bceSAndroid Build Coastguard Worker typedef VKAPI_ATTR VkResult(VKAPI_CALL *CreateDescriptorSetLayoutFunc)(
65*35238bceSAndroid Build Coastguard Worker     VkDevice device, const VkDescriptorSetLayoutCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator,
66*35238bceSAndroid Build Coastguard Worker     VkDescriptorSetLayout *pSetLayout);
67*35238bceSAndroid Build Coastguard Worker typedef VKAPI_ATTR void(VKAPI_CALL *DestroyDescriptorSetLayoutFunc)(VkDevice device,
68*35238bceSAndroid Build Coastguard Worker                                                                     VkDescriptorSetLayout descriptorSetLayout,
69*35238bceSAndroid Build Coastguard Worker                                                                     const VkAllocationCallbacks *pAllocator);
70*35238bceSAndroid Build Coastguard Worker typedef VKAPI_ATTR VkResult(VKAPI_CALL *CreatePipelineLayoutFunc)(VkDevice device,
71*35238bceSAndroid Build Coastguard Worker                                                                   const VkPipelineLayoutCreateInfo *pCreateInfo,
72*35238bceSAndroid Build Coastguard Worker                                                                   const VkAllocationCallbacks *pAllocator,
73*35238bceSAndroid Build Coastguard Worker                                                                   VkPipelineLayout *pPipelineLayout);
74*35238bceSAndroid Build Coastguard Worker typedef VKAPI_ATTR void(VKAPI_CALL *DestroyPipelineLayoutFunc)(VkDevice device, VkPipelineLayout pipelineLayout,
75*35238bceSAndroid Build Coastguard Worker                                                                const VkAllocationCallbacks *pAllocator);
76*35238bceSAndroid Build Coastguard Worker typedef VKAPI_ATTR VkResult(VKAPI_CALL *CreateGraphicsPipelinesFunc)(VkDevice device, VkPipelineCache pipelineCache,
77*35238bceSAndroid Build Coastguard Worker                                                                      uint32_t createInfoCount,
78*35238bceSAndroid Build Coastguard Worker                                                                      const VkGraphicsPipelineCreateInfo *pCreateInfos,
79*35238bceSAndroid Build Coastguard Worker                                                                      const VkAllocationCallbacks *pAllocator,
80*35238bceSAndroid Build Coastguard Worker                                                                      VkPipeline *pPipelines);
81*35238bceSAndroid Build Coastguard Worker typedef VKAPI_ATTR VkResult(VKAPI_CALL *CreateComputePipelinesFunc)(VkDevice device, VkPipelineCache pipelineCache,
82*35238bceSAndroid Build Coastguard Worker                                                                     uint32_t createInfoCount,
83*35238bceSAndroid Build Coastguard Worker                                                                     const VkComputePipelineCreateInfo *pCreateInfos,
84*35238bceSAndroid Build Coastguard Worker                                                                     const VkAllocationCallbacks *pAllocator,
85*35238bceSAndroid Build Coastguard Worker                                                                     VkPipeline *pPipelines);
86*35238bceSAndroid Build Coastguard Worker typedef VKAPI_ATTR void(VKAPI_CALL *DestroyPipelineFunc)(VkDevice device, VkPipeline pipeline,
87*35238bceSAndroid Build Coastguard Worker                                                          const VkAllocationCallbacks *pAllocator);
88*35238bceSAndroid Build Coastguard Worker typedef VKAPI_ATTR VkResult(VKAPI_CALL *CreatePipelineCacheFunc)(VkDevice device,
89*35238bceSAndroid Build Coastguard Worker                                                                  const VkPipelineCacheCreateInfo *pCreateInfo,
90*35238bceSAndroid Build Coastguard Worker                                                                  const VkAllocationCallbacks *pAllocator,
91*35238bceSAndroid Build Coastguard Worker                                                                  VkPipelineCache *pPipelineCache);
92*35238bceSAndroid Build Coastguard Worker typedef VKAPI_ATTR void(VKAPI_CALL *DestroyPipelineCacheFunc)(VkDevice device, VkPipelineCache pipelineCache,
93*35238bceSAndroid Build Coastguard Worker                                                               const VkAllocationCallbacks *pAllocator);
94*35238bceSAndroid Build Coastguard Worker typedef VKAPI_ATTR VkResult(VKAPI_CALL *GetPipelineCacheDataFunc)(VkDevice device, VkPipelineCache pipelineCache,
95*35238bceSAndroid Build Coastguard Worker                                                                   uintptr_t *pDataSize, void *pData);
96*35238bceSAndroid Build Coastguard Worker 
97*35238bceSAndroid Build Coastguard Worker } // namespace vk
98*35238bceSAndroid Build Coastguard Worker 
99*35238bceSAndroid Build Coastguard Worker namespace vksc_server
100*35238bceSAndroid Build Coastguard Worker {
101*35238bceSAndroid Build Coastguard Worker 
102*35238bceSAndroid Build Coastguard Worker const VkDeviceSize VKSC_DEFAULT_PIPELINE_POOL_SIZE = 2u * 1024u * 1024u;
103*35238bceSAndroid Build Coastguard Worker 
exportFilesForExternalCompiler(const VulkanPipelineCacheInput & input,const std::string & path,const std::string & filePrefix)104*35238bceSAndroid Build Coastguard Worker void exportFilesForExternalCompiler(const VulkanPipelineCacheInput &input, const std::string &path,
105*35238bceSAndroid Build Coastguard Worker                                     const std::string &filePrefix)
106*35238bceSAndroid Build Coastguard Worker {
107*35238bceSAndroid Build Coastguard Worker     // unpack JSON data to track relations between objects
108*35238bceSAndroid Build Coastguard Worker     using namespace vk;
109*35238bceSAndroid Build Coastguard Worker     using namespace json;
110*35238bceSAndroid Build Coastguard Worker     Context jsonReader;
111*35238bceSAndroid Build Coastguard Worker 
112*35238bceSAndroid Build Coastguard Worker     std::map<VkSamplerYcbcrConversion, VkSamplerYcbcrConversionCreateInfo> allSamplerYcbcrConversions;
113*35238bceSAndroid Build Coastguard Worker     for (auto &&samplerYcbcr : input.samplerYcbcrConversions)
114*35238bceSAndroid Build Coastguard Worker     {
115*35238bceSAndroid Build Coastguard Worker         VkSamplerYcbcrConversionCreateInfo sycCI{};
116*35238bceSAndroid Build Coastguard Worker         readJSON_VkSamplerYcbcrConversionCreateInfo(jsonReader, samplerYcbcr.second, sycCI);
117*35238bceSAndroid Build Coastguard Worker         allSamplerYcbcrConversions.insert({samplerYcbcr.first, sycCI});
118*35238bceSAndroid Build Coastguard Worker     }
119*35238bceSAndroid Build Coastguard Worker 
120*35238bceSAndroid Build Coastguard Worker     std::map<VkSampler, VkSamplerCreateInfo> allSamplers;
121*35238bceSAndroid Build Coastguard Worker     for (auto &&sampler : input.samplers)
122*35238bceSAndroid Build Coastguard Worker     {
123*35238bceSAndroid Build Coastguard Worker         VkSamplerCreateInfo sCI{};
124*35238bceSAndroid Build Coastguard Worker         readJSON_VkSamplerCreateInfo(jsonReader, sampler.second, sCI);
125*35238bceSAndroid Build Coastguard Worker         allSamplers.insert({sampler.first, sCI});
126*35238bceSAndroid Build Coastguard Worker     }
127*35238bceSAndroid Build Coastguard Worker 
128*35238bceSAndroid Build Coastguard Worker     std::map<VkShaderModule, VkShaderModuleCreateInfo> allShaderModules;
129*35238bceSAndroid Build Coastguard Worker     std::map<VkShaderModule, std::vector<uint8_t>> allSpirvShaders;
130*35238bceSAndroid Build Coastguard Worker     for (auto &&shader : input.shaderModules)
131*35238bceSAndroid Build Coastguard Worker     {
132*35238bceSAndroid Build Coastguard Worker         VkShaderModuleCreateInfo smCI{};
133*35238bceSAndroid Build Coastguard Worker         std::vector<uint8_t> spirvShader;
134*35238bceSAndroid Build Coastguard Worker         readJSON_VkShaderModuleCreateInfo(jsonReader, shader.second, smCI, spirvShader);
135*35238bceSAndroid Build Coastguard Worker         allShaderModules.insert({shader.first, smCI});
136*35238bceSAndroid Build Coastguard Worker         allSpirvShaders.insert({shader.first, spirvShader});
137*35238bceSAndroid Build Coastguard Worker     }
138*35238bceSAndroid Build Coastguard Worker 
139*35238bceSAndroid Build Coastguard Worker     std::map<VkRenderPass, VkRenderPassCreateInfo> allRenderPasses;
140*35238bceSAndroid Build Coastguard Worker     std::map<VkRenderPass, VkRenderPassCreateInfo2> allRenderPasses2;
141*35238bceSAndroid Build Coastguard Worker     for (auto &&renderPass : input.renderPasses)
142*35238bceSAndroid Build Coastguard Worker     {
143*35238bceSAndroid Build Coastguard Worker         if (renderPass.second.find("VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2") != std::string::npos)
144*35238bceSAndroid Build Coastguard Worker         {
145*35238bceSAndroid Build Coastguard Worker             VkRenderPassCreateInfo2 rpCI{};
146*35238bceSAndroid Build Coastguard Worker             readJSON_VkRenderPassCreateInfo2(jsonReader, renderPass.second, rpCI);
147*35238bceSAndroid Build Coastguard Worker             allRenderPasses2.insert({renderPass.first, rpCI});
148*35238bceSAndroid Build Coastguard Worker         }
149*35238bceSAndroid Build Coastguard Worker         else if (renderPass.second.find("VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO") != std::string::npos)
150*35238bceSAndroid Build Coastguard Worker         {
151*35238bceSAndroid Build Coastguard Worker             VkRenderPassCreateInfo rpCI{};
152*35238bceSAndroid Build Coastguard Worker             readJSON_VkRenderPassCreateInfo(jsonReader, renderPass.second, rpCI);
153*35238bceSAndroid Build Coastguard Worker             allRenderPasses.insert({renderPass.first, rpCI});
154*35238bceSAndroid Build Coastguard Worker         }
155*35238bceSAndroid Build Coastguard Worker         else
156*35238bceSAndroid Build Coastguard Worker             TCU_THROW(InternalError, "Could not recognize render pass type");
157*35238bceSAndroid Build Coastguard Worker     }
158*35238bceSAndroid Build Coastguard Worker 
159*35238bceSAndroid Build Coastguard Worker     std::map<VkDescriptorSetLayout, VkDescriptorSetLayoutCreateInfo> allDescriptorSetLayouts;
160*35238bceSAndroid Build Coastguard Worker     for (auto &&descriptorSetLayout : input.descriptorSetLayouts)
161*35238bceSAndroid Build Coastguard Worker     {
162*35238bceSAndroid Build Coastguard Worker         VkDescriptorSetLayoutCreateInfo dsCI{};
163*35238bceSAndroid Build Coastguard Worker         readJSON_VkDescriptorSetLayoutCreateInfo(jsonReader, descriptorSetLayout.second, dsCI);
164*35238bceSAndroid Build Coastguard Worker         allDescriptorSetLayouts.insert({descriptorSetLayout.first, dsCI});
165*35238bceSAndroid Build Coastguard Worker     }
166*35238bceSAndroid Build Coastguard Worker 
167*35238bceSAndroid Build Coastguard Worker     std::map<VkPipelineLayout, VkPipelineLayoutCreateInfo> allPipelineLayouts;
168*35238bceSAndroid Build Coastguard Worker     for (auto &&pipelineLayout : input.pipelineLayouts)
169*35238bceSAndroid Build Coastguard Worker     {
170*35238bceSAndroid Build Coastguard Worker         VkPipelineLayoutCreateInfo plCI{};
171*35238bceSAndroid Build Coastguard Worker         readJSON_VkPipelineLayoutCreateInfo(jsonReader, pipelineLayout.second, plCI);
172*35238bceSAndroid Build Coastguard Worker         allPipelineLayouts.insert({pipelineLayout.first, plCI});
173*35238bceSAndroid Build Coastguard Worker     }
174*35238bceSAndroid Build Coastguard Worker 
175*35238bceSAndroid Build Coastguard Worker     uint32_t exportedPipelines = 0;
176*35238bceSAndroid Build Coastguard Worker 
177*35238bceSAndroid Build Coastguard Worker     for (auto &&pipeline : input.pipelines)
178*35238bceSAndroid Build Coastguard Worker     {
179*35238bceSAndroid Build Coastguard Worker         // filter objects used for this specific pipeline ( graphics or compute )
180*35238bceSAndroid Build Coastguard Worker         std::map<VkSamplerYcbcrConversion, VkSamplerYcbcrConversionCreateInfo> samplerYcbcrConversions;
181*35238bceSAndroid Build Coastguard Worker         std::map<VkSampler, VkSamplerCreateInfo> samplers;
182*35238bceSAndroid Build Coastguard Worker         std::map<VkShaderModule, VkShaderModuleCreateInfo> shaderModules;
183*35238bceSAndroid Build Coastguard Worker         std::map<VkShaderModule, std::vector<uint8_t>> spirvShaders;
184*35238bceSAndroid Build Coastguard Worker         std::map<VkRenderPass, VkRenderPassCreateInfo> renderPasses;
185*35238bceSAndroid Build Coastguard Worker         std::map<VkRenderPass, VkRenderPassCreateInfo2> renderPasses2;
186*35238bceSAndroid Build Coastguard Worker         std::map<VkDescriptorSetLayout, VkDescriptorSetLayoutCreateInfo> descriptorSetLayouts;
187*35238bceSAndroid Build Coastguard Worker         std::map<VkPipelineLayout, VkPipelineLayoutCreateInfo> pipelineLayouts;
188*35238bceSAndroid Build Coastguard Worker 
189*35238bceSAndroid Build Coastguard Worker         if (pipeline.pipelineContents.find("VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO") != std::string::npos)
190*35238bceSAndroid Build Coastguard Worker         {
191*35238bceSAndroid Build Coastguard Worker             VkGraphicsPipelineCreateInfo gpCI{};
192*35238bceSAndroid Build Coastguard Worker             readJSON_VkGraphicsPipelineCreateInfo(jsonReader, pipeline.pipelineContents, gpCI);
193*35238bceSAndroid Build Coastguard Worker 
194*35238bceSAndroid Build Coastguard Worker             // copy all used shaders
195*35238bceSAndroid Build Coastguard Worker             for (uint32_t i = 0; i < gpCI.stageCount; ++i)
196*35238bceSAndroid Build Coastguard Worker             {
197*35238bceSAndroid Build Coastguard Worker                 auto it = allShaderModules.find(gpCI.pStages[i].module);
198*35238bceSAndroid Build Coastguard Worker                 if (it == end(allShaderModules))
199*35238bceSAndroid Build Coastguard Worker                     TCU_THROW(InternalError, "Could not find shader module");
200*35238bceSAndroid Build Coastguard Worker                 shaderModules.insert(*it);
201*35238bceSAndroid Build Coastguard Worker 
202*35238bceSAndroid Build Coastguard Worker                 auto it2 = allSpirvShaders.find(gpCI.pStages[i].module);
203*35238bceSAndroid Build Coastguard Worker                 if (it2 == end(allSpirvShaders))
204*35238bceSAndroid Build Coastguard Worker                     TCU_THROW(InternalError, "Could not find shader");
205*35238bceSAndroid Build Coastguard Worker                 spirvShaders.insert(*it2);
206*35238bceSAndroid Build Coastguard Worker             }
207*35238bceSAndroid Build Coastguard Worker 
208*35238bceSAndroid Build Coastguard Worker             // copy render pass
209*35238bceSAndroid Build Coastguard Worker             {
210*35238bceSAndroid Build Coastguard Worker                 auto it = allRenderPasses.find(gpCI.renderPass);
211*35238bceSAndroid Build Coastguard Worker                 if (it == end(allRenderPasses))
212*35238bceSAndroid Build Coastguard Worker                 {
213*35238bceSAndroid Build Coastguard Worker                     auto it2 = allRenderPasses2.find(gpCI.renderPass);
214*35238bceSAndroid Build Coastguard Worker                     if (it2 == end(allRenderPasses2))
215*35238bceSAndroid Build Coastguard Worker                         TCU_THROW(InternalError, "Could not find render pass");
216*35238bceSAndroid Build Coastguard Worker                     else
217*35238bceSAndroid Build Coastguard Worker                         renderPasses2.insert(*it2);
218*35238bceSAndroid Build Coastguard Worker                 }
219*35238bceSAndroid Build Coastguard Worker                 else
220*35238bceSAndroid Build Coastguard Worker                     renderPasses.insert(*it);
221*35238bceSAndroid Build Coastguard Worker             }
222*35238bceSAndroid Build Coastguard Worker 
223*35238bceSAndroid Build Coastguard Worker             // copy pipeline layout
224*35238bceSAndroid Build Coastguard Worker             {
225*35238bceSAndroid Build Coastguard Worker                 auto it = allPipelineLayouts.find(gpCI.layout);
226*35238bceSAndroid Build Coastguard Worker                 if (it == end(allPipelineLayouts))
227*35238bceSAndroid Build Coastguard Worker                     TCU_THROW(InternalError, "Could not find pipeline layout");
228*35238bceSAndroid Build Coastguard Worker                 pipelineLayouts.insert(*it);
229*35238bceSAndroid Build Coastguard Worker 
230*35238bceSAndroid Build Coastguard Worker                 // copy descriptor set layouts
231*35238bceSAndroid Build Coastguard Worker                 for (uint32_t i = 0; i < it->second.setLayoutCount; ++i)
232*35238bceSAndroid Build Coastguard Worker                 {
233*35238bceSAndroid Build Coastguard Worker                     auto it2 = allDescriptorSetLayouts.find(it->second.pSetLayouts[i]);
234*35238bceSAndroid Build Coastguard Worker                     if (it2 == end(allDescriptorSetLayouts))
235*35238bceSAndroid Build Coastguard Worker                         TCU_THROW(InternalError, "Could not find descriptor set layout");
236*35238bceSAndroid Build Coastguard Worker                     descriptorSetLayouts.insert({it2->first, it2->second});
237*35238bceSAndroid Build Coastguard Worker 
238*35238bceSAndroid Build Coastguard Worker                     // copy samplers
239*35238bceSAndroid Build Coastguard Worker                     for (uint32_t j = 0; j < it2->second.bindingCount; ++j)
240*35238bceSAndroid Build Coastguard Worker                     {
241*35238bceSAndroid Build Coastguard Worker                         if (it2->second.pBindings[j].pImmutableSamplers != DE_NULL)
242*35238bceSAndroid Build Coastguard Worker                         {
243*35238bceSAndroid Build Coastguard Worker                             for (uint32_t k = 0; k < it2->second.pBindings[j].descriptorCount; ++k)
244*35238bceSAndroid Build Coastguard Worker                             {
245*35238bceSAndroid Build Coastguard Worker                                 auto it3 = allSamplers.find(it2->second.pBindings[j].pImmutableSamplers[k]);
246*35238bceSAndroid Build Coastguard Worker                                 if (it3 == end(allSamplers))
247*35238bceSAndroid Build Coastguard Worker                                     TCU_THROW(InternalError, "Could not find sampler");
248*35238bceSAndroid Build Coastguard Worker                                 samplers.insert({it3->first, it3->second});
249*35238bceSAndroid Build Coastguard Worker 
250*35238bceSAndroid Build Coastguard Worker                                 // copy sampler YcbcrConversion
251*35238bceSAndroid Build Coastguard Worker                                 if (it3->second.pNext != DE_NULL)
252*35238bceSAndroid Build Coastguard Worker                                 {
253*35238bceSAndroid Build Coastguard Worker                                     VkSamplerYcbcrConversionInfo *info =
254*35238bceSAndroid Build Coastguard Worker                                         (VkSamplerYcbcrConversionInfo *)findStructureInChain(
255*35238bceSAndroid Build Coastguard Worker                                             it3->second.pNext, VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO);
256*35238bceSAndroid Build Coastguard Worker                                     if (info->sType == VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO)
257*35238bceSAndroid Build Coastguard Worker                                     {
258*35238bceSAndroid Build Coastguard Worker                                         auto it4 = allSamplerYcbcrConversions.find(info->conversion);
259*35238bceSAndroid Build Coastguard Worker                                         if (it4 == end(allSamplerYcbcrConversions))
260*35238bceSAndroid Build Coastguard Worker                                             TCU_THROW(InternalError, "Could not find VkSamplerYcbcrConversion");
261*35238bceSAndroid Build Coastguard Worker                                         samplerYcbcrConversions.insert({it4->first, it4->second});
262*35238bceSAndroid Build Coastguard Worker                                     }
263*35238bceSAndroid Build Coastguard Worker                                 }
264*35238bceSAndroid Build Coastguard Worker                             }
265*35238bceSAndroid Build Coastguard Worker                         }
266*35238bceSAndroid Build Coastguard Worker                     }
267*35238bceSAndroid Build Coastguard Worker                 }
268*35238bceSAndroid Build Coastguard Worker             }
269*35238bceSAndroid Build Coastguard Worker 
270*35238bceSAndroid Build Coastguard Worker             vk::VkPhysicalDeviceFeatures2 deviceFeatures2;
271*35238bceSAndroid Build Coastguard Worker             readJSON_VkPhysicalDeviceFeatures2(jsonReader, pipeline.deviceFeatures, deviceFeatures2);
272*35238bceSAndroid Build Coastguard Worker 
273*35238bceSAndroid Build Coastguard Worker             // export shaders and objects to JSON compatible with https://schema.khronos.org/vulkan/vkpcc.json
274*35238bceSAndroid Build Coastguard Worker             std::string gpTxt = writeJSON_GraphicsPipeline_vkpccjson(
275*35238bceSAndroid Build Coastguard Worker                 filePrefix, exportedPipelines, pipeline.id, gpCI, deviceFeatures2, pipeline.deviceExtensions,
276*35238bceSAndroid Build Coastguard Worker                 samplerYcbcrConversions, samplers, descriptorSetLayouts, renderPasses, renderPasses2, pipelineLayouts);
277*35238bceSAndroid Build Coastguard Worker             std::stringstream fileName;
278*35238bceSAndroid Build Coastguard Worker #ifdef _WIN32
279*35238bceSAndroid Build Coastguard Worker             fileName << path << "\\" << filePrefix << "graphics_pipeline_" << exportedPipelines << ".json";
280*35238bceSAndroid Build Coastguard Worker #else
281*35238bceSAndroid Build Coastguard Worker             fileName << path << "/" << filePrefix << "graphics_pipeline_" << exportedPipelines << ".json";
282*35238bceSAndroid Build Coastguard Worker #endif
283*35238bceSAndroid Build Coastguard Worker             {
284*35238bceSAndroid Build Coastguard Worker                 std::ofstream oFile(fileName.str().c_str(), std::ios::out);
285*35238bceSAndroid Build Coastguard Worker                 oFile << gpTxt;
286*35238bceSAndroid Build Coastguard Worker             }
287*35238bceSAndroid Build Coastguard Worker 
288*35238bceSAndroid Build Coastguard Worker             for (uint32_t j = 0; j < gpCI.stageCount; ++j)
289*35238bceSAndroid Build Coastguard Worker             {
290*35238bceSAndroid Build Coastguard Worker                 std::stringstream shaderName;
291*35238bceSAndroid Build Coastguard Worker #ifdef _WIN32
292*35238bceSAndroid Build Coastguard Worker                 shaderName << path << "\\" << filePrefix << "shader_" << exportedPipelines << "_"
293*35238bceSAndroid Build Coastguard Worker                            << gpCI.pStages[j].module.getInternal() << ".";
294*35238bceSAndroid Build Coastguard Worker #else
295*35238bceSAndroid Build Coastguard Worker                 shaderName << path << "/" << filePrefix << "shader_" << exportedPipelines << "_"
296*35238bceSAndroid Build Coastguard Worker                            << gpCI.pStages[j].module.getInternal() << ".";
297*35238bceSAndroid Build Coastguard Worker #endif
298*35238bceSAndroid Build Coastguard Worker                 switch (gpCI.pStages[j].stage)
299*35238bceSAndroid Build Coastguard Worker                 {
300*35238bceSAndroid Build Coastguard Worker                 case VK_SHADER_STAGE_VERTEX_BIT:
301*35238bceSAndroid Build Coastguard Worker                     shaderName << "vert";
302*35238bceSAndroid Build Coastguard Worker                     break;
303*35238bceSAndroid Build Coastguard Worker                 case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
304*35238bceSAndroid Build Coastguard Worker                     shaderName << "tesc";
305*35238bceSAndroid Build Coastguard Worker                     break;
306*35238bceSAndroid Build Coastguard Worker                 case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
307*35238bceSAndroid Build Coastguard Worker                     shaderName << "tese";
308*35238bceSAndroid Build Coastguard Worker                     break;
309*35238bceSAndroid Build Coastguard Worker                 case VK_SHADER_STAGE_GEOMETRY_BIT:
310*35238bceSAndroid Build Coastguard Worker                     shaderName << "geom";
311*35238bceSAndroid Build Coastguard Worker                     break;
312*35238bceSAndroid Build Coastguard Worker                 case VK_SHADER_STAGE_FRAGMENT_BIT:
313*35238bceSAndroid Build Coastguard Worker                     shaderName << "frag";
314*35238bceSAndroid Build Coastguard Worker                     break;
315*35238bceSAndroid Build Coastguard Worker                 default:
316*35238bceSAndroid Build Coastguard Worker                     TCU_THROW(InternalError, "Unrecognized shader stage");
317*35238bceSAndroid Build Coastguard Worker                 }
318*35238bceSAndroid Build Coastguard Worker                 shaderName << ".spv";
319*35238bceSAndroid Build Coastguard Worker 
320*35238bceSAndroid Build Coastguard Worker                 auto sit = spirvShaders.find(gpCI.pStages[j].module);
321*35238bceSAndroid Build Coastguard Worker                 if (sit == end(spirvShaders))
322*35238bceSAndroid Build Coastguard Worker                     TCU_THROW(InternalError, "SPIR-V shader not found");
323*35238bceSAndroid Build Coastguard Worker 
324*35238bceSAndroid Build Coastguard Worker                 std::ofstream oFile(shaderName.str().c_str(), std::ios::out | std::ios::binary);
325*35238bceSAndroid Build Coastguard Worker                 oFile.write((const char *)sit->second.data(), sit->second.size());
326*35238bceSAndroid Build Coastguard Worker             }
327*35238bceSAndroid Build Coastguard Worker 
328*35238bceSAndroid Build Coastguard Worker             exportedPipelines++;
329*35238bceSAndroid Build Coastguard Worker         }
330*35238bceSAndroid Build Coastguard Worker         else if (pipeline.pipelineContents.find("VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO") != std::string::npos)
331*35238bceSAndroid Build Coastguard Worker         {
332*35238bceSAndroid Build Coastguard Worker             VkComputePipelineCreateInfo cpCI{};
333*35238bceSAndroid Build Coastguard Worker             readJSON_VkComputePipelineCreateInfo(jsonReader, pipeline.pipelineContents, cpCI);
334*35238bceSAndroid Build Coastguard Worker 
335*35238bceSAndroid Build Coastguard Worker             // copy shader
336*35238bceSAndroid Build Coastguard Worker             {
337*35238bceSAndroid Build Coastguard Worker                 auto it = allShaderModules.find(cpCI.stage.module);
338*35238bceSAndroid Build Coastguard Worker                 if (it == end(allShaderModules))
339*35238bceSAndroid Build Coastguard Worker                     TCU_THROW(InternalError, "Could not find shader module");
340*35238bceSAndroid Build Coastguard Worker                 shaderModules.insert(*it);
341*35238bceSAndroid Build Coastguard Worker 
342*35238bceSAndroid Build Coastguard Worker                 auto it2 = allSpirvShaders.find(cpCI.stage.module);
343*35238bceSAndroid Build Coastguard Worker                 if (it2 == end(allSpirvShaders))
344*35238bceSAndroid Build Coastguard Worker                     TCU_THROW(InternalError, "Could not find shader");
345*35238bceSAndroid Build Coastguard Worker                 spirvShaders.insert(*it2);
346*35238bceSAndroid Build Coastguard Worker             }
347*35238bceSAndroid Build Coastguard Worker 
348*35238bceSAndroid Build Coastguard Worker             // copy pipeline layout
349*35238bceSAndroid Build Coastguard Worker             {
350*35238bceSAndroid Build Coastguard Worker                 auto it = allPipelineLayouts.find(cpCI.layout);
351*35238bceSAndroid Build Coastguard Worker                 if (it == end(allPipelineLayouts))
352*35238bceSAndroid Build Coastguard Worker                     TCU_THROW(InternalError, "Could not find pipeline layout");
353*35238bceSAndroid Build Coastguard Worker                 pipelineLayouts.insert(*it);
354*35238bceSAndroid Build Coastguard Worker 
355*35238bceSAndroid Build Coastguard Worker                 // copy descriptor set layouts
356*35238bceSAndroid Build Coastguard Worker                 for (uint32_t i = 0; i < it->second.setLayoutCount; ++i)
357*35238bceSAndroid Build Coastguard Worker                 {
358*35238bceSAndroid Build Coastguard Worker                     auto it2 = allDescriptorSetLayouts.find(it->second.pSetLayouts[i]);
359*35238bceSAndroid Build Coastguard Worker                     if (it2 == end(allDescriptorSetLayouts))
360*35238bceSAndroid Build Coastguard Worker                         TCU_THROW(InternalError, "Could not find descriptor set layout");
361*35238bceSAndroid Build Coastguard Worker                     descriptorSetLayouts.insert({it2->first, it2->second});
362*35238bceSAndroid Build Coastguard Worker 
363*35238bceSAndroid Build Coastguard Worker                     // copy samplers
364*35238bceSAndroid Build Coastguard Worker                     for (uint32_t j = 0; j < it2->second.bindingCount; ++j)
365*35238bceSAndroid Build Coastguard Worker                     {
366*35238bceSAndroid Build Coastguard Worker                         if (it2->second.pBindings[j].pImmutableSamplers != DE_NULL)
367*35238bceSAndroid Build Coastguard Worker                         {
368*35238bceSAndroid Build Coastguard Worker                             for (uint32_t k = 0; k < it2->second.pBindings[j].descriptorCount; ++k)
369*35238bceSAndroid Build Coastguard Worker                             {
370*35238bceSAndroid Build Coastguard Worker                                 auto it3 = allSamplers.find(it2->second.pBindings[j].pImmutableSamplers[k]);
371*35238bceSAndroid Build Coastguard Worker                                 if (it3 == end(allSamplers))
372*35238bceSAndroid Build Coastguard Worker                                     TCU_THROW(InternalError, "Could not find sampler");
373*35238bceSAndroid Build Coastguard Worker                                 samplers.insert({it3->first, it3->second});
374*35238bceSAndroid Build Coastguard Worker 
375*35238bceSAndroid Build Coastguard Worker                                 // copy sampler YcbcrConversion
376*35238bceSAndroid Build Coastguard Worker                                 if (it3->second.pNext != DE_NULL)
377*35238bceSAndroid Build Coastguard Worker                                 {
378*35238bceSAndroid Build Coastguard Worker                                     VkSamplerYcbcrConversionInfo *info =
379*35238bceSAndroid Build Coastguard Worker                                         (VkSamplerYcbcrConversionInfo *)(it3->second.pNext);
380*35238bceSAndroid Build Coastguard Worker                                     if (info->sType == VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO)
381*35238bceSAndroid Build Coastguard Worker                                     {
382*35238bceSAndroid Build Coastguard Worker                                         auto it4 = allSamplerYcbcrConversions.find(info->conversion);
383*35238bceSAndroid Build Coastguard Worker                                         if (it4 == end(allSamplerYcbcrConversions))
384*35238bceSAndroid Build Coastguard Worker                                             TCU_THROW(InternalError, "Could not find VkSamplerYcbcrConversion");
385*35238bceSAndroid Build Coastguard Worker                                         samplerYcbcrConversions.insert({it4->first, it4->second});
386*35238bceSAndroid Build Coastguard Worker                                     }
387*35238bceSAndroid Build Coastguard Worker                                 }
388*35238bceSAndroid Build Coastguard Worker                             }
389*35238bceSAndroid Build Coastguard Worker                         }
390*35238bceSAndroid Build Coastguard Worker                     }
391*35238bceSAndroid Build Coastguard Worker                 }
392*35238bceSAndroid Build Coastguard Worker             }
393*35238bceSAndroid Build Coastguard Worker             vk::VkPhysicalDeviceFeatures2 deviceFeatures2;
394*35238bceSAndroid Build Coastguard Worker             readJSON_VkPhysicalDeviceFeatures2(jsonReader, pipeline.deviceFeatures, deviceFeatures2);
395*35238bceSAndroid Build Coastguard Worker 
396*35238bceSAndroid Build Coastguard Worker             // export shaders and objects to JSON compatible with https://schema.khronos.org/vulkan/vkpcc.json
397*35238bceSAndroid Build Coastguard Worker             std::string cpTxt = writeJSON_ComputePipeline_vkpccjson(
398*35238bceSAndroid Build Coastguard Worker                 filePrefix, exportedPipelines, pipeline.id, cpCI, deviceFeatures2, pipeline.deviceExtensions,
399*35238bceSAndroid Build Coastguard Worker                 samplerYcbcrConversions, samplers, descriptorSetLayouts, pipelineLayouts);
400*35238bceSAndroid Build Coastguard Worker             std::stringstream fileName;
401*35238bceSAndroid Build Coastguard Worker #ifdef _WIN32
402*35238bceSAndroid Build Coastguard Worker             fileName << path << "\\" << filePrefix << "compute_pipeline_" << exportedPipelines << ".json";
403*35238bceSAndroid Build Coastguard Worker #else
404*35238bceSAndroid Build Coastguard Worker             fileName << path << "/" << filePrefix << "compute_pipeline_" << exportedPipelines << ".json";
405*35238bceSAndroid Build Coastguard Worker #endif
406*35238bceSAndroid Build Coastguard Worker             {
407*35238bceSAndroid Build Coastguard Worker                 std::ofstream oFile(fileName.str().c_str(), std::ios::out);
408*35238bceSAndroid Build Coastguard Worker                 oFile << cpTxt;
409*35238bceSAndroid Build Coastguard Worker             }
410*35238bceSAndroid Build Coastguard Worker 
411*35238bceSAndroid Build Coastguard Worker             {
412*35238bceSAndroid Build Coastguard Worker                 std::stringstream shaderName;
413*35238bceSAndroid Build Coastguard Worker #ifdef _WIN32
414*35238bceSAndroid Build Coastguard Worker                 shaderName << path << "\\" << filePrefix << "shader_" << exportedPipelines << "_"
415*35238bceSAndroid Build Coastguard Worker                            << cpCI.stage.module.getInternal() << ".";
416*35238bceSAndroid Build Coastguard Worker #else
417*35238bceSAndroid Build Coastguard Worker                 shaderName << path << "/" << filePrefix << "shader_" << exportedPipelines << "_"
418*35238bceSAndroid Build Coastguard Worker                            << cpCI.stage.module.getInternal() << ".";
419*35238bceSAndroid Build Coastguard Worker #endif
420*35238bceSAndroid Build Coastguard Worker                 switch (cpCI.stage.stage)
421*35238bceSAndroid Build Coastguard Worker                 {
422*35238bceSAndroid Build Coastguard Worker                 case VK_SHADER_STAGE_COMPUTE_BIT:
423*35238bceSAndroid Build Coastguard Worker                     shaderName << "comp";
424*35238bceSAndroid Build Coastguard Worker                     break;
425*35238bceSAndroid Build Coastguard Worker                 default:
426*35238bceSAndroid Build Coastguard Worker                     TCU_THROW(InternalError, "Unrecognized shader stage");
427*35238bceSAndroid Build Coastguard Worker                 }
428*35238bceSAndroid Build Coastguard Worker                 shaderName << ".spv";
429*35238bceSAndroid Build Coastguard Worker 
430*35238bceSAndroid Build Coastguard Worker                 auto sit = spirvShaders.find(cpCI.stage.module);
431*35238bceSAndroid Build Coastguard Worker                 if (sit == end(spirvShaders))
432*35238bceSAndroid Build Coastguard Worker                     TCU_THROW(InternalError, "SPIR-V shader not found");
433*35238bceSAndroid Build Coastguard Worker 
434*35238bceSAndroid Build Coastguard Worker                 std::ofstream oFile(shaderName.str().c_str(), std::ios::out | std::ios::binary);
435*35238bceSAndroid Build Coastguard Worker                 oFile.write((const char *)sit->second.data(), sit->second.size());
436*35238bceSAndroid Build Coastguard Worker             }
437*35238bceSAndroid Build Coastguard Worker 
438*35238bceSAndroid Build Coastguard Worker             exportedPipelines++;
439*35238bceSAndroid Build Coastguard Worker         }
440*35238bceSAndroid Build Coastguard Worker     }
441*35238bceSAndroid Build Coastguard Worker }
442*35238bceSAndroid Build Coastguard Worker 
443*35238bceSAndroid Build Coastguard Worker // This is function prototype for creating pipeline cache using offline pipeline compiler
444*35238bceSAndroid Build Coastguard Worker 
buildOfflinePipelineCache(const VulkanPipelineCacheInput & input,const std::string & pipelineCompilerPath,const std::string & pipelineCompilerDataDir,const std::string & pipelineCompilerArgs,const std::string & pipelineCompilerOutputFile,const std::string & pipelineCompilerLogFile,const std::string & pipelineCompilerFilePrefix)445*35238bceSAndroid Build Coastguard Worker vector<u8> buildOfflinePipelineCache(const VulkanPipelineCacheInput &input, const std::string &pipelineCompilerPath,
446*35238bceSAndroid Build Coastguard Worker                                      const std::string &pipelineCompilerDataDir,
447*35238bceSAndroid Build Coastguard Worker                                      const std::string &pipelineCompilerArgs,
448*35238bceSAndroid Build Coastguard Worker                                      const std::string &pipelineCompilerOutputFile,
449*35238bceSAndroid Build Coastguard Worker                                      const std::string &pipelineCompilerLogFile,
450*35238bceSAndroid Build Coastguard Worker                                      const std::string &pipelineCompilerFilePrefix)
451*35238bceSAndroid Build Coastguard Worker {
452*35238bceSAndroid Build Coastguard Worker     if (!deFileExists(pipelineCompilerPath.c_str()))
453*35238bceSAndroid Build Coastguard Worker         TCU_THROW(InternalError, std::string("Can't find pipeline compiler") + pipelineCompilerPath);
454*35238bceSAndroid Build Coastguard Worker     // Remove all files from output directory
455*35238bceSAndroid Build Coastguard Worker     for (de::DirectoryIterator iter(pipelineCompilerDataDir); iter.hasItem(); iter.next())
456*35238bceSAndroid Build Coastguard Worker     {
457*35238bceSAndroid Build Coastguard Worker         const de::FilePath filePath = iter.getItem();
458*35238bceSAndroid Build Coastguard Worker         if (filePath.getType() != de::FilePath::TYPE_FILE)
459*35238bceSAndroid Build Coastguard Worker             continue;
460*35238bceSAndroid Build Coastguard Worker         if (!pipelineCompilerFilePrefix.empty() && filePath.getBaseName().find(pipelineCompilerFilePrefix) != 0)
461*35238bceSAndroid Build Coastguard Worker             continue;
462*35238bceSAndroid Build Coastguard Worker         deDeleteFile(filePath.getPath());
463*35238bceSAndroid Build Coastguard Worker     }
464*35238bceSAndroid Build Coastguard Worker 
465*35238bceSAndroid Build Coastguard Worker     // export new files
466*35238bceSAndroid Build Coastguard Worker     exportFilesForExternalCompiler(input, pipelineCompilerDataDir, pipelineCompilerFilePrefix);
467*35238bceSAndroid Build Coastguard Worker     if (input.pipelines.size() == 0)
468*35238bceSAndroid Build Coastguard Worker         return vector<u8>();
469*35238bceSAndroid Build Coastguard Worker 
470*35238bceSAndroid Build Coastguard Worker     // run offline pipeline compiler
471*35238bceSAndroid Build Coastguard Worker     {
472*35238bceSAndroid Build Coastguard Worker         std::stringstream compilerCommand;
473*35238bceSAndroid Build Coastguard Worker         compilerCommand << pipelineCompilerPath << " --path " << pipelineCompilerDataDir << " --out "
474*35238bceSAndroid Build Coastguard Worker                         << pipelineCompilerOutputFile;
475*35238bceSAndroid Build Coastguard Worker         if (!pipelineCompilerLogFile.empty())
476*35238bceSAndroid Build Coastguard Worker             compilerCommand << " --log " << pipelineCompilerLogFile;
477*35238bceSAndroid Build Coastguard Worker         if (!pipelineCompilerFilePrefix.empty())
478*35238bceSAndroid Build Coastguard Worker             compilerCommand << " --prefix " << pipelineCompilerFilePrefix;
479*35238bceSAndroid Build Coastguard Worker         if (!pipelineCompilerArgs.empty())
480*35238bceSAndroid Build Coastguard Worker             compilerCommand << " " << pipelineCompilerArgs;
481*35238bceSAndroid Build Coastguard Worker 
482*35238bceSAndroid Build Coastguard Worker         std::string command = compilerCommand.str();
483*35238bceSAndroid Build Coastguard Worker         int returnValue     = system(command.c_str());
484*35238bceSAndroid Build Coastguard Worker         // offline pipeline compiler returns EXIT_SUCCESS on success
485*35238bceSAndroid Build Coastguard Worker         if (returnValue != EXIT_SUCCESS)
486*35238bceSAndroid Build Coastguard Worker         {
487*35238bceSAndroid Build Coastguard Worker             TCU_THROW(InternalError, "offline pipeline compilation failed");
488*35238bceSAndroid Build Coastguard Worker         }
489*35238bceSAndroid Build Coastguard Worker     }
490*35238bceSAndroid Build Coastguard Worker 
491*35238bceSAndroid Build Coastguard Worker     // read created pipeline cache into result vector
492*35238bceSAndroid Build Coastguard Worker     vector<u8> result;
493*35238bceSAndroid Build Coastguard Worker     {
494*35238bceSAndroid Build Coastguard Worker         std::ifstream iFile(pipelineCompilerOutputFile.c_str(), std::ios::in | std::ios::binary);
495*35238bceSAndroid Build Coastguard Worker         if (!iFile)
496*35238bceSAndroid Build Coastguard Worker             TCU_THROW(InternalError, (std::string("Cannot open file ") + pipelineCompilerOutputFile).c_str());
497*35238bceSAndroid Build Coastguard Worker 
498*35238bceSAndroid Build Coastguard Worker         auto fileBegin = iFile.tellg();
499*35238bceSAndroid Build Coastguard Worker         iFile.seekg(0, std::ios::end);
500*35238bceSAndroid Build Coastguard Worker         auto fileEnd = iFile.tellg();
501*35238bceSAndroid Build Coastguard Worker         iFile.seekg(0, std::ios::beg);
502*35238bceSAndroid Build Coastguard Worker         std::size_t fileSize = static_cast<std::size_t>(fileEnd - fileBegin);
503*35238bceSAndroid Build Coastguard Worker         if (fileSize > 0)
504*35238bceSAndroid Build Coastguard Worker         {
505*35238bceSAndroid Build Coastguard Worker             result.resize(fileSize);
506*35238bceSAndroid Build Coastguard Worker             iFile.read(reinterpret_cast<char *>(result.data()), fileSize);
507*35238bceSAndroid Build Coastguard Worker             if (iFile.fail())
508*35238bceSAndroid Build Coastguard Worker                 TCU_THROW(InternalError, (std::string("Cannot load file ") + pipelineCompilerOutputFile).c_str());
509*35238bceSAndroid Build Coastguard Worker         }
510*35238bceSAndroid Build Coastguard Worker     }
511*35238bceSAndroid Build Coastguard Worker     return result;
512*35238bceSAndroid Build Coastguard Worker }
513*35238bceSAndroid Build Coastguard Worker 
buildPipelineCache(const VulkanPipelineCacheInput & input,const vk::PlatformInterface & vkp,vk::VkInstance instance,const vk::InstanceInterface & vki,vk::VkPhysicalDevice physicalDevice,uint32_t queueIndex)514*35238bceSAndroid Build Coastguard Worker vector<u8> buildPipelineCache(const VulkanPipelineCacheInput &input, const vk::PlatformInterface &vkp,
515*35238bceSAndroid Build Coastguard Worker                               vk::VkInstance instance, const vk::InstanceInterface &vki,
516*35238bceSAndroid Build Coastguard Worker                               vk::VkPhysicalDevice physicalDevice, uint32_t queueIndex)
517*35238bceSAndroid Build Coastguard Worker {
518*35238bceSAndroid Build Coastguard Worker     using namespace vk;
519*35238bceSAndroid Build Coastguard Worker     using namespace json;
520*35238bceSAndroid Build Coastguard Worker 
521*35238bceSAndroid Build Coastguard Worker     Context jsonReader;
522*35238bceSAndroid Build Coastguard Worker 
523*35238bceSAndroid Build Coastguard Worker     // sort pipelines by device features and extensions
524*35238bceSAndroid Build Coastguard Worker     std::vector<VulkanJsonPipelineDescription> pipelines = input.pipelines;
525*35238bceSAndroid Build Coastguard Worker     std::sort(begin(pipelines), end(pipelines),
526*35238bceSAndroid Build Coastguard Worker               [](const VulkanJsonPipelineDescription &lhs, const VulkanJsonPipelineDescription &rhs)
527*35238bceSAndroid Build Coastguard Worker               {
528*35238bceSAndroid Build Coastguard Worker                   if (lhs.deviceExtensions != rhs.deviceExtensions)
529*35238bceSAndroid Build Coastguard Worker                       return lhs.deviceExtensions < rhs.deviceExtensions;
530*35238bceSAndroid Build Coastguard Worker                   return lhs.deviceFeatures < rhs.deviceFeatures;
531*35238bceSAndroid Build Coastguard Worker               });
532*35238bceSAndroid Build Coastguard Worker 
533*35238bceSAndroid Build Coastguard Worker     std::string deviceFeatures                = "<empty>";
534*35238bceSAndroid Build Coastguard Worker     std::vector<std::string> deviceExtensions = {"<empty>"};
535*35238bceSAndroid Build Coastguard Worker 
536*35238bceSAndroid Build Coastguard Worker     Move<VkDevice> pcDevice;
537*35238bceSAndroid Build Coastguard Worker     VkPipelineCache pipelineCache;
538*35238bceSAndroid Build Coastguard Worker     vector<u8> resultCacheData;
539*35238bceSAndroid Build Coastguard Worker 
540*35238bceSAndroid Build Coastguard Worker     GetDeviceProcAddrFunc getDeviceProcAddrFunc                         = DE_NULL;
541*35238bceSAndroid Build Coastguard Worker     CreateSamplerYcbcrConversionFunc createSamplerYcbcrConversionFunc   = DE_NULL;
542*35238bceSAndroid Build Coastguard Worker     DestroySamplerYcbcrConversionFunc destroySamplerYcbcrConversionFunc = DE_NULL;
543*35238bceSAndroid Build Coastguard Worker     CreateSamplerFunc createSamplerFunc                                 = DE_NULL;
544*35238bceSAndroid Build Coastguard Worker     DestroySamplerFunc destroySamplerFunc                               = DE_NULL;
545*35238bceSAndroid Build Coastguard Worker     CreateShaderModuleFunc createShaderModuleFunc                       = DE_NULL;
546*35238bceSAndroid Build Coastguard Worker     DestroyShaderModuleFunc destroyShaderModuleFunc                     = DE_NULL;
547*35238bceSAndroid Build Coastguard Worker     CreateRenderPassFunc createRenderPassFunc                           = DE_NULL;
548*35238bceSAndroid Build Coastguard Worker     CreateRenderPass2Func createRenderPass2Func                         = DE_NULL;
549*35238bceSAndroid Build Coastguard Worker     DestroyRenderPassFunc destroyRenderPassFunc                         = DE_NULL;
550*35238bceSAndroid Build Coastguard Worker     CreateDescriptorSetLayoutFunc createDescriptorSetLayoutFunc         = DE_NULL;
551*35238bceSAndroid Build Coastguard Worker     DestroyDescriptorSetLayoutFunc destroyDescriptorSetLayoutFunc       = DE_NULL;
552*35238bceSAndroid Build Coastguard Worker     CreatePipelineLayoutFunc createPipelineLayoutFunc                   = DE_NULL;
553*35238bceSAndroid Build Coastguard Worker     DestroyPipelineLayoutFunc destroyPipelineLayoutFunc                 = DE_NULL;
554*35238bceSAndroid Build Coastguard Worker     CreateGraphicsPipelinesFunc createGraphicsPipelinesFunc             = DE_NULL;
555*35238bceSAndroid Build Coastguard Worker     CreateComputePipelinesFunc createComputePipelinesFunc               = DE_NULL;
556*35238bceSAndroid Build Coastguard Worker     CreatePipelineCacheFunc createPipelineCacheFunc                     = DE_NULL;
557*35238bceSAndroid Build Coastguard Worker     DestroyPipelineCacheFunc destroyPipelineCacheFunc                   = DE_NULL;
558*35238bceSAndroid Build Coastguard Worker     DestroyPipelineFunc destroyPipelineFunc                             = DE_NULL;
559*35238bceSAndroid Build Coastguard Worker     GetPipelineCacheDataFunc getPipelineCacheDataFunc                   = DE_NULL;
560*35238bceSAndroid Build Coastguard Worker 
561*35238bceSAndroid Build Coastguard Worker     std::map<VkSamplerYcbcrConversion, VkSamplerYcbcrConversion> falseToRealSamplerYcbcrConversions;
562*35238bceSAndroid Build Coastguard Worker     std::map<VkSampler, VkSampler> falseToRealSamplers;
563*35238bceSAndroid Build Coastguard Worker     std::map<VkShaderModule, VkShaderModule> falseToRealShaderModules;
564*35238bceSAndroid Build Coastguard Worker     std::map<VkRenderPass, VkRenderPass> falseToRealRenderPasses;
565*35238bceSAndroid Build Coastguard Worker     std::map<VkDescriptorSetLayout, VkDescriptorSetLayout> falseToRealDescriptorSetLayouts;
566*35238bceSAndroid Build Coastguard Worker     std::map<VkPipelineLayout, VkPipelineLayout> falseToRealPipelineLayouts;
567*35238bceSAndroid Build Coastguard Worker 
568*35238bceSAndroid Build Coastguard Worker     // decode VkGraphicsPipelineCreateInfo and VkComputePipelineCreateInfo structs and create VkPipelines with a given pipeline cache
569*35238bceSAndroid Build Coastguard Worker     for (auto &&pipeline : pipelines)
570*35238bceSAndroid Build Coastguard Worker     {
571*35238bceSAndroid Build Coastguard Worker         // check if we need to create new device
572*35238bceSAndroid Build Coastguard Worker         if (pcDevice.get() == DE_NULL || deviceFeatures != pipeline.deviceFeatures ||
573*35238bceSAndroid Build Coastguard Worker             deviceExtensions != pipeline.deviceExtensions)
574*35238bceSAndroid Build Coastguard Worker         {
575*35238bceSAndroid Build Coastguard Worker             // remove old device
576*35238bceSAndroid Build Coastguard Worker             if (pcDevice.get() != DE_NULL)
577*35238bceSAndroid Build Coastguard Worker             {
578*35238bceSAndroid Build Coastguard Worker                 // collect cache data
579*35238bceSAndroid Build Coastguard Worker                 std::size_t cacheSize;
580*35238bceSAndroid Build Coastguard Worker                 VK_CHECK(getPipelineCacheDataFunc(*pcDevice, pipelineCache, &cacheSize, DE_NULL));
581*35238bceSAndroid Build Coastguard Worker                 resultCacheData.resize(cacheSize);
582*35238bceSAndroid Build Coastguard Worker                 VK_CHECK(getPipelineCacheDataFunc(*pcDevice, pipelineCache, &cacheSize, resultCacheData.data()));
583*35238bceSAndroid Build Coastguard Worker 
584*35238bceSAndroid Build Coastguard Worker                 // clean up resources - in ResourceInterfaceStandard we just simulate Vulkan SC driver after all...
585*35238bceSAndroid Build Coastguard Worker                 for (auto &&it : falseToRealPipelineLayouts)
586*35238bceSAndroid Build Coastguard Worker                     destroyPipelineLayoutFunc(*pcDevice, it.second, DE_NULL);
587*35238bceSAndroid Build Coastguard Worker                 for (auto &&it : falseToRealDescriptorSetLayouts)
588*35238bceSAndroid Build Coastguard Worker                     destroyDescriptorSetLayoutFunc(*pcDevice, it.second, DE_NULL);
589*35238bceSAndroid Build Coastguard Worker                 for (auto &&it : falseToRealRenderPasses)
590*35238bceSAndroid Build Coastguard Worker                     destroyRenderPassFunc(*pcDevice, it.second, DE_NULL);
591*35238bceSAndroid Build Coastguard Worker                 for (auto &&it : falseToRealShaderModules)
592*35238bceSAndroid Build Coastguard Worker                     destroyShaderModuleFunc(*pcDevice, it.second, DE_NULL);
593*35238bceSAndroid Build Coastguard Worker                 for (auto &&it : falseToRealSamplers)
594*35238bceSAndroid Build Coastguard Worker                     destroySamplerFunc(*pcDevice, it.second, DE_NULL);
595*35238bceSAndroid Build Coastguard Worker                 for (auto &&it : falseToRealSamplerYcbcrConversions)
596*35238bceSAndroid Build Coastguard Worker                     destroySamplerYcbcrConversionFunc(*pcDevice, it.second, DE_NULL);
597*35238bceSAndroid Build Coastguard Worker                 destroyPipelineCacheFunc(*pcDevice, pipelineCache, DE_NULL);
598*35238bceSAndroid Build Coastguard Worker 
599*35238bceSAndroid Build Coastguard Worker                 // clear maps
600*35238bceSAndroid Build Coastguard Worker                 falseToRealSamplerYcbcrConversions.clear();
601*35238bceSAndroid Build Coastguard Worker                 falseToRealSamplers.clear();
602*35238bceSAndroid Build Coastguard Worker                 falseToRealShaderModules.clear();
603*35238bceSAndroid Build Coastguard Worker                 falseToRealRenderPasses.clear();
604*35238bceSAndroid Build Coastguard Worker                 falseToRealDescriptorSetLayouts.clear();
605*35238bceSAndroid Build Coastguard Worker                 falseToRealPipelineLayouts.clear();
606*35238bceSAndroid Build Coastguard Worker 
607*35238bceSAndroid Build Coastguard Worker                 // remove device
608*35238bceSAndroid Build Coastguard Worker                 pcDevice = Move<VkDevice>();
609*35238bceSAndroid Build Coastguard Worker             }
610*35238bceSAndroid Build Coastguard Worker 
611*35238bceSAndroid Build Coastguard Worker             // create new device with proper features and extensions
612*35238bceSAndroid Build Coastguard Worker             const float queuePriority                           = 1.0f;
613*35238bceSAndroid Build Coastguard Worker             const VkDeviceQueueCreateInfo deviceQueueCreateInfo = {
614*35238bceSAndroid Build Coastguard Worker                 VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
615*35238bceSAndroid Build Coastguard Worker                 DE_NULL,
616*35238bceSAndroid Build Coastguard Worker                 (VkDeviceQueueCreateFlags)0u,
617*35238bceSAndroid Build Coastguard Worker                 queueIndex,     //queueFamilyIndex;
618*35238bceSAndroid Build Coastguard Worker                 1,              //queueCount;
619*35238bceSAndroid Build Coastguard Worker                 &queuePriority, //pQueuePriorities;
620*35238bceSAndroid Build Coastguard Worker             };
621*35238bceSAndroid Build Coastguard Worker 
622*35238bceSAndroid Build Coastguard Worker             // recreate pNext chain. Add required Vulkan SC objects if they're missing
623*35238bceSAndroid Build Coastguard Worker             void *pNextChain                           = readJSON_pNextChain(jsonReader, pipeline.deviceFeatures);
624*35238bceSAndroid Build Coastguard Worker             VkPhysicalDeviceFeatures2 *chainedFeatures = (VkPhysicalDeviceFeatures2 *)findStructureInChain(
625*35238bceSAndroid Build Coastguard Worker                 pNextChain, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2);
626*35238bceSAndroid Build Coastguard Worker             VkPhysicalDeviceFeatures2 localFeatures = initVulkanStructure();
627*35238bceSAndroid Build Coastguard Worker             VkDeviceObjectReservationCreateInfo *chainedObjReservation =
628*35238bceSAndroid Build Coastguard Worker                 (VkDeviceObjectReservationCreateInfo *)findStructureInChain(
629*35238bceSAndroid Build Coastguard Worker                     pNextChain, VK_STRUCTURE_TYPE_DEVICE_OBJECT_RESERVATION_CREATE_INFO);
630*35238bceSAndroid Build Coastguard Worker             VkDeviceObjectReservationCreateInfo localObjReservation = resetDeviceObjectReservationCreateInfo();
631*35238bceSAndroid Build Coastguard Worker             VkPhysicalDeviceVulkanSC10Features *chainedSC10Features =
632*35238bceSAndroid Build Coastguard Worker                 (VkPhysicalDeviceVulkanSC10Features *)findStructureInChain(
633*35238bceSAndroid Build Coastguard Worker                     pNextChain, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_SC_1_0_FEATURES);
634*35238bceSAndroid Build Coastguard Worker             VkPhysicalDeviceVulkanSC10Features localSC10Features = createDefaultSC10Features();
635*35238bceSAndroid Build Coastguard Worker 
636*35238bceSAndroid Build Coastguard Worker             void *pNext = pNextChain;
637*35238bceSAndroid Build Coastguard Worker             if (chainedFeatures == DE_NULL)
638*35238bceSAndroid Build Coastguard Worker             {
639*35238bceSAndroid Build Coastguard Worker                 chainedFeatures     = &localFeatures;
640*35238bceSAndroid Build Coastguard Worker                 localFeatures.pNext = pNext;
641*35238bceSAndroid Build Coastguard Worker                 pNext               = &localFeatures;
642*35238bceSAndroid Build Coastguard Worker             }
643*35238bceSAndroid Build Coastguard Worker             if (chainedObjReservation == DE_NULL)
644*35238bceSAndroid Build Coastguard Worker             {
645*35238bceSAndroid Build Coastguard Worker                 chainedObjReservation     = &localObjReservation;
646*35238bceSAndroid Build Coastguard Worker                 localObjReservation.pNext = pNext;
647*35238bceSAndroid Build Coastguard Worker                 pNext                     = &localObjReservation;
648*35238bceSAndroid Build Coastguard Worker             }
649*35238bceSAndroid Build Coastguard Worker             if (chainedSC10Features == DE_NULL)
650*35238bceSAndroid Build Coastguard Worker             {
651*35238bceSAndroid Build Coastguard Worker                 chainedSC10Features     = &localSC10Features;
652*35238bceSAndroid Build Coastguard Worker                 localSC10Features.pNext = pNext;
653*35238bceSAndroid Build Coastguard Worker                 pNext                   = &localSC10Features;
654*35238bceSAndroid Build Coastguard Worker             }
655*35238bceSAndroid Build Coastguard Worker 
656*35238bceSAndroid Build Coastguard Worker             uint32_t gPipelineCount = 0U;
657*35238bceSAndroid Build Coastguard Worker             uint32_t cPipelineCount = 0U;
658*35238bceSAndroid Build Coastguard Worker             for (auto &&pipeline2 : pipelines)
659*35238bceSAndroid Build Coastguard Worker             {
660*35238bceSAndroid Build Coastguard Worker                 if (pipeline2.deviceFeatures != pipeline.deviceFeatures ||
661*35238bceSAndroid Build Coastguard Worker                     pipeline2.deviceExtensions != pipeline.deviceExtensions)
662*35238bceSAndroid Build Coastguard Worker                     continue;
663*35238bceSAndroid Build Coastguard Worker                 if (pipeline2.pipelineContents.find("VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO") !=
664*35238bceSAndroid Build Coastguard Worker                     std::string::npos)
665*35238bceSAndroid Build Coastguard Worker                     gPipelineCount++;
666*35238bceSAndroid Build Coastguard Worker                 else if (pipeline2.pipelineContents.find("VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO") !=
667*35238bceSAndroid Build Coastguard Worker                          std::string::npos)
668*35238bceSAndroid Build Coastguard Worker                     cPipelineCount++;
669*35238bceSAndroid Build Coastguard Worker             }
670*35238bceSAndroid Build Coastguard Worker 
671*35238bceSAndroid Build Coastguard Worker             // declare pipeline pool size
672*35238bceSAndroid Build Coastguard Worker             VkPipelinePoolSize poolSize = {
673*35238bceSAndroid Build Coastguard Worker                 VK_STRUCTURE_TYPE_PIPELINE_POOL_SIZE, // VkStructureType sType;
674*35238bceSAndroid Build Coastguard Worker                 DE_NULL,                              // const void* pNext;
675*35238bceSAndroid Build Coastguard Worker                 VKSC_DEFAULT_PIPELINE_POOL_SIZE,      // VkDeviceSize poolEntrySize;
676*35238bceSAndroid Build Coastguard Worker                 gPipelineCount + cPipelineCount       // uint32_t poolEntryCount;
677*35238bceSAndroid Build Coastguard Worker             };
678*35238bceSAndroid Build Coastguard Worker             chainedObjReservation->pipelinePoolSizeCount = 1u;
679*35238bceSAndroid Build Coastguard Worker             chainedObjReservation->pPipelinePoolSizes    = &poolSize;
680*35238bceSAndroid Build Coastguard Worker 
681*35238bceSAndroid Build Coastguard Worker             // declare pipeline cache
682*35238bceSAndroid Build Coastguard Worker             VkPipelineCacheCreateInfo pcCI = {
683*35238bceSAndroid Build Coastguard Worker                 VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO,              // VkStructureType sType;
684*35238bceSAndroid Build Coastguard Worker                 DE_NULL,                                                   // const void* pNext;
685*35238bceSAndroid Build Coastguard Worker                 (VkPipelineCacheCreateFlags)0u,                            // VkPipelineCacheCreateFlags flags;
686*35238bceSAndroid Build Coastguard Worker                 resultCacheData.size(),                                    // size_t initialDataSize;
687*35238bceSAndroid Build Coastguard Worker                 resultCacheData.empty() ? DE_NULL : resultCacheData.data() // const void* pInitialData;
688*35238bceSAndroid Build Coastguard Worker             };
689*35238bceSAndroid Build Coastguard Worker             chainedObjReservation->pipelineCacheCreateInfoCount = 1u;
690*35238bceSAndroid Build Coastguard Worker             chainedObjReservation->pPipelineCacheCreateInfos    = &pcCI;
691*35238bceSAndroid Build Coastguard Worker 
692*35238bceSAndroid Build Coastguard Worker             chainedObjReservation->pipelineLayoutRequestCount =
693*35238bceSAndroid Build Coastguard Worker                 de::max(chainedObjReservation->pipelineLayoutRequestCount, uint32_t(input.pipelineLayouts.size()));
694*35238bceSAndroid Build Coastguard Worker             chainedObjReservation->renderPassRequestCount =
695*35238bceSAndroid Build Coastguard Worker                 de::max(chainedObjReservation->renderPassRequestCount, uint32_t(input.renderPasses.size()));
696*35238bceSAndroid Build Coastguard Worker             chainedObjReservation->graphicsPipelineRequestCount =
697*35238bceSAndroid Build Coastguard Worker                 de::max(chainedObjReservation->graphicsPipelineRequestCount, gPipelineCount);
698*35238bceSAndroid Build Coastguard Worker             chainedObjReservation->computePipelineRequestCount =
699*35238bceSAndroid Build Coastguard Worker                 de::max(chainedObjReservation->computePipelineRequestCount, cPipelineCount);
700*35238bceSAndroid Build Coastguard Worker             chainedObjReservation->descriptorSetLayoutRequestCount = de::max(
701*35238bceSAndroid Build Coastguard Worker                 chainedObjReservation->descriptorSetLayoutRequestCount, uint32_t(input.descriptorSetLayouts.size()));
702*35238bceSAndroid Build Coastguard Worker             chainedObjReservation->samplerRequestCount =
703*35238bceSAndroid Build Coastguard Worker                 de::max(chainedObjReservation->samplerRequestCount, uint32_t(input.samplers.size()));
704*35238bceSAndroid Build Coastguard Worker             chainedObjReservation->samplerYcbcrConversionRequestCount =
705*35238bceSAndroid Build Coastguard Worker                 de::max(chainedObjReservation->samplerYcbcrConversionRequestCount,
706*35238bceSAndroid Build Coastguard Worker                         uint32_t(input.samplerYcbcrConversions.size()));
707*35238bceSAndroid Build Coastguard Worker             chainedObjReservation->pipelineCacheRequestCount =
708*35238bceSAndroid Build Coastguard Worker                 de::max(chainedObjReservation->pipelineCacheRequestCount, 1u);
709*35238bceSAndroid Build Coastguard Worker 
710*35238bceSAndroid Build Coastguard Worker             // decode all VkDescriptorSetLayoutCreateInfo
711*35238bceSAndroid Build Coastguard Worker             std::map<VkDescriptorSetLayout, VkDescriptorSetLayoutCreateInfo> descriptorSetLayoutCreateInfos;
712*35238bceSAndroid Build Coastguard Worker             for (auto &&descriptorSetLayout : input.descriptorSetLayouts)
713*35238bceSAndroid Build Coastguard Worker             {
714*35238bceSAndroid Build Coastguard Worker                 VkDescriptorSetLayoutCreateInfo dsCI{};
715*35238bceSAndroid Build Coastguard Worker                 readJSON_VkDescriptorSetLayoutCreateInfo(jsonReader, descriptorSetLayout.second, dsCI);
716*35238bceSAndroid Build Coastguard Worker                 descriptorSetLayoutCreateInfos.insert({descriptorSetLayout.first, dsCI});
717*35238bceSAndroid Build Coastguard Worker             }
718*35238bceSAndroid Build Coastguard Worker 
719*35238bceSAndroid Build Coastguard Worker             chainedObjReservation->descriptorSetLayoutBindingLimit = 1u;
720*35238bceSAndroid Build Coastguard Worker             for (auto &&dsCI : descriptorSetLayoutCreateInfos)
721*35238bceSAndroid Build Coastguard Worker                 for (uint32_t i = 0; i < dsCI.second.bindingCount; ++i)
722*35238bceSAndroid Build Coastguard Worker                     chainedObjReservation->descriptorSetLayoutBindingLimit = de::max(
723*35238bceSAndroid Build Coastguard Worker                         chainedObjReservation->descriptorSetLayoutBindingLimit, dsCI.second.pBindings[i].binding + 1u);
724*35238bceSAndroid Build Coastguard Worker 
725*35238bceSAndroid Build Coastguard Worker             // recreate device extensions
726*35238bceSAndroid Build Coastguard Worker             vector<const char *> deviceExts;
727*35238bceSAndroid Build Coastguard Worker             for (auto &&ext : pipeline.deviceExtensions)
728*35238bceSAndroid Build Coastguard Worker                 deviceExts.push_back(ext.data());
729*35238bceSAndroid Build Coastguard Worker 
730*35238bceSAndroid Build Coastguard Worker             const VkDeviceCreateInfo deviceCreateInfo = {
731*35238bceSAndroid Build Coastguard Worker                 VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,             // sType
732*35238bceSAndroid Build Coastguard Worker                 pNext,                                            // pNext
733*35238bceSAndroid Build Coastguard Worker                 (VkDeviceCreateFlags)0u,                          // flags
734*35238bceSAndroid Build Coastguard Worker                 1,                                                // queueRecordCount
735*35238bceSAndroid Build Coastguard Worker                 &deviceQueueCreateInfo,                           // pRequestedQueues
736*35238bceSAndroid Build Coastguard Worker                 0,                                                // layerCount
737*35238bceSAndroid Build Coastguard Worker                 DE_NULL,                                          // ppEnabledLayerNames
738*35238bceSAndroid Build Coastguard Worker                 (uint32_t)deviceExts.size(),                      // extensionCount
739*35238bceSAndroid Build Coastguard Worker                 deviceExts.empty() ? DE_NULL : deviceExts.data(), // ppEnabledExtensionNames
740*35238bceSAndroid Build Coastguard Worker                 &(chainedFeatures->features)                      // pEnabledFeatures
741*35238bceSAndroid Build Coastguard Worker             };
742*35238bceSAndroid Build Coastguard Worker 
743*35238bceSAndroid Build Coastguard Worker             // create new device
744*35238bceSAndroid Build Coastguard Worker             pcDevice         = createDevice(vkp, instance, vki, physicalDevice, &deviceCreateInfo);
745*35238bceSAndroid Build Coastguard Worker             deviceFeatures   = pipeline.deviceFeatures;
746*35238bceSAndroid Build Coastguard Worker             deviceExtensions = pipeline.deviceExtensions;
747*35238bceSAndroid Build Coastguard Worker 
748*35238bceSAndroid Build Coastguard Worker             // create local function pointers required to perform pipeline cache creation
749*35238bceSAndroid Build Coastguard Worker             getDeviceProcAddrFunc = (GetDeviceProcAddrFunc)vkp.getInstanceProcAddr(instance, "vkGetDeviceProcAddr");
750*35238bceSAndroid Build Coastguard Worker             createSamplerYcbcrConversionFunc =
751*35238bceSAndroid Build Coastguard Worker                 (CreateSamplerYcbcrConversionFunc)getDeviceProcAddrFunc(*pcDevice, "vkCreateSamplerYcbcrConversion");
752*35238bceSAndroid Build Coastguard Worker             destroySamplerYcbcrConversionFunc =
753*35238bceSAndroid Build Coastguard Worker                 (DestroySamplerYcbcrConversionFunc)getDeviceProcAddrFunc(*pcDevice, "vkDestroySamplerYcbcrConversion");
754*35238bceSAndroid Build Coastguard Worker             createSamplerFunc      = (CreateSamplerFunc)getDeviceProcAddrFunc(*pcDevice, "vkCreateSampler");
755*35238bceSAndroid Build Coastguard Worker             destroySamplerFunc     = (DestroySamplerFunc)getDeviceProcAddrFunc(*pcDevice, "vkDestroySampler");
756*35238bceSAndroid Build Coastguard Worker             createShaderModuleFunc = (CreateShaderModuleFunc)getDeviceProcAddrFunc(*pcDevice, "vkCreateShaderModule");
757*35238bceSAndroid Build Coastguard Worker             destroyShaderModuleFunc =
758*35238bceSAndroid Build Coastguard Worker                 (DestroyShaderModuleFunc)getDeviceProcAddrFunc(*pcDevice, "vkDestroyShaderModule");
759*35238bceSAndroid Build Coastguard Worker             createRenderPassFunc  = (CreateRenderPassFunc)getDeviceProcAddrFunc(*pcDevice, "vkCreateRenderPass");
760*35238bceSAndroid Build Coastguard Worker             createRenderPass2Func = (CreateRenderPass2Func)getDeviceProcAddrFunc(*pcDevice, "vkCreateRenderPass2");
761*35238bceSAndroid Build Coastguard Worker             destroyRenderPassFunc = (DestroyRenderPassFunc)getDeviceProcAddrFunc(*pcDevice, "vkDestroyRenderPass");
762*35238bceSAndroid Build Coastguard Worker             createDescriptorSetLayoutFunc =
763*35238bceSAndroid Build Coastguard Worker                 (CreateDescriptorSetLayoutFunc)getDeviceProcAddrFunc(*pcDevice, "vkCreateDescriptorSetLayout");
764*35238bceSAndroid Build Coastguard Worker             destroyDescriptorSetLayoutFunc =
765*35238bceSAndroid Build Coastguard Worker                 (DestroyDescriptorSetLayoutFunc)getDeviceProcAddrFunc(*pcDevice, "vkDestroyDescriptorSetLayout");
766*35238bceSAndroid Build Coastguard Worker             createPipelineLayoutFunc =
767*35238bceSAndroid Build Coastguard Worker                 (CreatePipelineLayoutFunc)getDeviceProcAddrFunc(*pcDevice, "vkCreatePipelineLayout");
768*35238bceSAndroid Build Coastguard Worker             destroyPipelineLayoutFunc =
769*35238bceSAndroid Build Coastguard Worker                 (DestroyPipelineLayoutFunc)getDeviceProcAddrFunc(*pcDevice, "vkDestroyPipelineLayout");
770*35238bceSAndroid Build Coastguard Worker             createGraphicsPipelinesFunc =
771*35238bceSAndroid Build Coastguard Worker                 (CreateGraphicsPipelinesFunc)getDeviceProcAddrFunc(*pcDevice, "vkCreateGraphicsPipelines");
772*35238bceSAndroid Build Coastguard Worker             createComputePipelinesFunc =
773*35238bceSAndroid Build Coastguard Worker                 (CreateComputePipelinesFunc)getDeviceProcAddrFunc(*pcDevice, "vkCreateComputePipelines");
774*35238bceSAndroid Build Coastguard Worker             createPipelineCacheFunc =
775*35238bceSAndroid Build Coastguard Worker                 (CreatePipelineCacheFunc)getDeviceProcAddrFunc(*pcDevice, "vkCreatePipelineCache");
776*35238bceSAndroid Build Coastguard Worker             destroyPipelineCacheFunc =
777*35238bceSAndroid Build Coastguard Worker                 (DestroyPipelineCacheFunc)getDeviceProcAddrFunc(*pcDevice, "vkDestroyPipelineCache");
778*35238bceSAndroid Build Coastguard Worker             destroyPipelineFunc = (DestroyPipelineFunc)getDeviceProcAddrFunc(*pcDevice, "vkDestroyPipeline");
779*35238bceSAndroid Build Coastguard Worker             getPipelineCacheDataFunc =
780*35238bceSAndroid Build Coastguard Worker                 (GetPipelineCacheDataFunc)getDeviceProcAddrFunc(*pcDevice, "vkGetPipelineCacheData");
781*35238bceSAndroid Build Coastguard Worker 
782*35238bceSAndroid Build Coastguard Worker             VK_CHECK(createPipelineCacheFunc(*pcDevice, &pcCI, DE_NULL, &pipelineCache));
783*35238bceSAndroid Build Coastguard Worker 
784*35238bceSAndroid Build Coastguard Worker             // decode VkSamplerYcbcrConversionCreateInfo structs and create VkSamplerYcbcrConversions
785*35238bceSAndroid Build Coastguard Worker             for (auto &&samplerYcbcr : input.samplerYcbcrConversions)
786*35238bceSAndroid Build Coastguard Worker             {
787*35238bceSAndroid Build Coastguard Worker                 VkSamplerYcbcrConversionCreateInfo sycCI{};
788*35238bceSAndroid Build Coastguard Worker                 readJSON_VkSamplerYcbcrConversionCreateInfo(jsonReader, samplerYcbcr.second, sycCI);
789*35238bceSAndroid Build Coastguard Worker                 VkSamplerYcbcrConversion realConversion;
790*35238bceSAndroid Build Coastguard Worker                 VK_CHECK(createSamplerYcbcrConversionFunc(*pcDevice, &sycCI, DE_NULL, &realConversion));
791*35238bceSAndroid Build Coastguard Worker                 falseToRealSamplerYcbcrConversions.insert({samplerYcbcr.first, realConversion});
792*35238bceSAndroid Build Coastguard Worker             }
793*35238bceSAndroid Build Coastguard Worker 
794*35238bceSAndroid Build Coastguard Worker             // decode VkSamplerCreateInfo structs and create VkSamplers
795*35238bceSAndroid Build Coastguard Worker             for (auto &&sampler : input.samplers)
796*35238bceSAndroid Build Coastguard Worker             {
797*35238bceSAndroid Build Coastguard Worker                 VkSamplerCreateInfo sCI{};
798*35238bceSAndroid Build Coastguard Worker                 readJSON_VkSamplerCreateInfo(jsonReader, sampler.second, sCI);
799*35238bceSAndroid Build Coastguard Worker 
800*35238bceSAndroid Build Coastguard Worker                 // replace ycbcr conversions if required
801*35238bceSAndroid Build Coastguard Worker                 if (sCI.pNext != NULL)
802*35238bceSAndroid Build Coastguard Worker                 {
803*35238bceSAndroid Build Coastguard Worker                     if (sCI.pNext != DE_NULL)
804*35238bceSAndroid Build Coastguard Worker                     {
805*35238bceSAndroid Build Coastguard Worker                         VkSamplerYcbcrConversionInfo *info = (VkSamplerYcbcrConversionInfo *)(sCI.pNext);
806*35238bceSAndroid Build Coastguard Worker                         if (info->sType == VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO)
807*35238bceSAndroid Build Coastguard Worker                         {
808*35238bceSAndroid Build Coastguard Worker                             auto jt = falseToRealSamplerYcbcrConversions.find(info->conversion);
809*35238bceSAndroid Build Coastguard Worker                             if (jt == end(falseToRealSamplerYcbcrConversions))
810*35238bceSAndroid Build Coastguard Worker                                 TCU_THROW(InternalError, "VkSamplerYcbcrConversion not found");
811*35238bceSAndroid Build Coastguard Worker                             info->conversion = jt->second;
812*35238bceSAndroid Build Coastguard Worker                         }
813*35238bceSAndroid Build Coastguard Worker                     }
814*35238bceSAndroid Build Coastguard Worker                 }
815*35238bceSAndroid Build Coastguard Worker 
816*35238bceSAndroid Build Coastguard Worker                 VkSampler realSampler;
817*35238bceSAndroid Build Coastguard Worker                 VK_CHECK(createSamplerFunc(*pcDevice, &sCI, DE_NULL, &realSampler));
818*35238bceSAndroid Build Coastguard Worker                 falseToRealSamplers.insert({sampler.first, realSampler});
819*35238bceSAndroid Build Coastguard Worker             }
820*35238bceSAndroid Build Coastguard Worker 
821*35238bceSAndroid Build Coastguard Worker             // decode VkShaderModuleCreateInfo structs and create VkShaderModules
822*35238bceSAndroid Build Coastguard Worker             for (auto &&shader : input.shaderModules)
823*35238bceSAndroid Build Coastguard Worker             {
824*35238bceSAndroid Build Coastguard Worker                 VkShaderModuleCreateInfo smCI{};
825*35238bceSAndroid Build Coastguard Worker                 std::vector<uint8_t> spirvShader;
826*35238bceSAndroid Build Coastguard Worker                 readJSON_VkShaderModuleCreateInfo(jsonReader, shader.second, smCI, spirvShader);
827*35238bceSAndroid Build Coastguard Worker                 VkShaderModule realShaderModule;
828*35238bceSAndroid Build Coastguard Worker                 VK_CHECK(createShaderModuleFunc(*pcDevice, &smCI, DE_NULL, &realShaderModule));
829*35238bceSAndroid Build Coastguard Worker                 falseToRealShaderModules.insert({shader.first, realShaderModule});
830*35238bceSAndroid Build Coastguard Worker             }
831*35238bceSAndroid Build Coastguard Worker 
832*35238bceSAndroid Build Coastguard Worker             // decode renderPass structs and create VkRenderPasses
833*35238bceSAndroid Build Coastguard Worker             for (auto &&renderPass : input.renderPasses)
834*35238bceSAndroid Build Coastguard Worker             {
835*35238bceSAndroid Build Coastguard Worker                 if (renderPass.second.find("VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2") != std::string::npos)
836*35238bceSAndroid Build Coastguard Worker                 {
837*35238bceSAndroid Build Coastguard Worker                     VkRenderPassCreateInfo2 rpCI{};
838*35238bceSAndroid Build Coastguard Worker                     readJSON_VkRenderPassCreateInfo2(jsonReader, renderPass.second, rpCI);
839*35238bceSAndroid Build Coastguard Worker                     VkRenderPass realRenderPass;
840*35238bceSAndroid Build Coastguard Worker                     VK_CHECK(createRenderPass2Func(*pcDevice, &rpCI, DE_NULL, &realRenderPass));
841*35238bceSAndroid Build Coastguard Worker                     falseToRealRenderPasses.insert({renderPass.first, realRenderPass});
842*35238bceSAndroid Build Coastguard Worker                 }
843*35238bceSAndroid Build Coastguard Worker                 else if (renderPass.second.find("VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO") != std::string::npos)
844*35238bceSAndroid Build Coastguard Worker                 {
845*35238bceSAndroid Build Coastguard Worker                     VkRenderPassCreateInfo rpCI{};
846*35238bceSAndroid Build Coastguard Worker                     readJSON_VkRenderPassCreateInfo(jsonReader, renderPass.second, rpCI);
847*35238bceSAndroid Build Coastguard Worker                     VkRenderPass realRenderPass;
848*35238bceSAndroid Build Coastguard Worker                     VK_CHECK(createRenderPassFunc(*pcDevice, &rpCI, DE_NULL, &realRenderPass));
849*35238bceSAndroid Build Coastguard Worker                     falseToRealRenderPasses.insert({renderPass.first, realRenderPass});
850*35238bceSAndroid Build Coastguard Worker                 }
851*35238bceSAndroid Build Coastguard Worker                 else
852*35238bceSAndroid Build Coastguard Worker                     TCU_THROW(InternalError, "Could not recognize render pass type");
853*35238bceSAndroid Build Coastguard Worker             }
854*35238bceSAndroid Build Coastguard Worker 
855*35238bceSAndroid Build Coastguard Worker             // create VkDescriptorSetLayouts
856*35238bceSAndroid Build Coastguard Worker             for (auto &&dsCI : descriptorSetLayoutCreateInfos)
857*35238bceSAndroid Build Coastguard Worker             {
858*35238bceSAndroid Build Coastguard Worker                 std::vector<VkDescriptorSetLayoutBinding> newDescriptorBindings;
859*35238bceSAndroid Build Coastguard Worker                 std::vector<std::vector<VkSampler>> realSamplers;
860*35238bceSAndroid Build Coastguard Worker 
861*35238bceSAndroid Build Coastguard Worker                 // we have to replace all bindings if there is any immutable sampler defined
862*35238bceSAndroid Build Coastguard Worker                 bool needReplaceSamplers = false;
863*35238bceSAndroid Build Coastguard Worker                 for (uint32_t i = 0; i < dsCI.second.bindingCount; ++i)
864*35238bceSAndroid Build Coastguard Worker                 {
865*35238bceSAndroid Build Coastguard Worker                     if (dsCI.second.pBindings[i].pImmutableSamplers != DE_NULL)
866*35238bceSAndroid Build Coastguard Worker                         needReplaceSamplers = true;
867*35238bceSAndroid Build Coastguard Worker                 }
868*35238bceSAndroid Build Coastguard Worker 
869*35238bceSAndroid Build Coastguard Worker                 if (needReplaceSamplers)
870*35238bceSAndroid Build Coastguard Worker                 {
871*35238bceSAndroid Build Coastguard Worker                     for (uint32_t i = 0; i < dsCI.second.bindingCount; ++i)
872*35238bceSAndroid Build Coastguard Worker                     {
873*35238bceSAndroid Build Coastguard Worker                         if (dsCI.second.pBindings[i].pImmutableSamplers == DE_NULL)
874*35238bceSAndroid Build Coastguard Worker                         {
875*35238bceSAndroid Build Coastguard Worker                             newDescriptorBindings.push_back(dsCI.second.pBindings[i]);
876*35238bceSAndroid Build Coastguard Worker                             continue;
877*35238bceSAndroid Build Coastguard Worker                         }
878*35238bceSAndroid Build Coastguard Worker 
879*35238bceSAndroid Build Coastguard Worker                         realSamplers.push_back(std::vector<VkSampler>(dsCI.second.pBindings[i].descriptorCount));
880*35238bceSAndroid Build Coastguard Worker                         for (uint32_t j = 0; j < dsCI.second.pBindings[i].descriptorCount; ++j)
881*35238bceSAndroid Build Coastguard Worker                         {
882*35238bceSAndroid Build Coastguard Worker                             if (dsCI.second.pBindings[i].pImmutableSamplers[j] == DE_NULL)
883*35238bceSAndroid Build Coastguard Worker                             {
884*35238bceSAndroid Build Coastguard Worker                                 realSamplers.back()[j] = DE_NULL;
885*35238bceSAndroid Build Coastguard Worker                                 continue;
886*35238bceSAndroid Build Coastguard Worker                             }
887*35238bceSAndroid Build Coastguard Worker                             else
888*35238bceSAndroid Build Coastguard Worker                             {
889*35238bceSAndroid Build Coastguard Worker                                 auto jt = falseToRealSamplers.find(dsCI.second.pBindings[i].pImmutableSamplers[j]);
890*35238bceSAndroid Build Coastguard Worker                                 if (jt == end(falseToRealSamplers))
891*35238bceSAndroid Build Coastguard Worker                                     TCU_THROW(InternalError, "VkSampler not found");
892*35238bceSAndroid Build Coastguard Worker                                 realSamplers.back()[j] = jt->second;
893*35238bceSAndroid Build Coastguard Worker                             }
894*35238bceSAndroid Build Coastguard Worker                         }
895*35238bceSAndroid Build Coastguard Worker                         VkDescriptorSetLayoutBinding bCopy = {
896*35238bceSAndroid Build Coastguard Worker                             dsCI.second.pBindings[i].binding,         // uint32_t binding;
897*35238bceSAndroid Build Coastguard Worker                             dsCI.second.pBindings[i].descriptorType,  // VkDescriptorType descriptorType;
898*35238bceSAndroid Build Coastguard Worker                             dsCI.second.pBindings[i].descriptorCount, // uint32_t descriptorCount;
899*35238bceSAndroid Build Coastguard Worker                             dsCI.second.pBindings[i].stageFlags,      // VkShaderStageFlags stageFlags;
900*35238bceSAndroid Build Coastguard Worker                             realSamplers.back().data()                // const VkSampler* pImmutableSamplers;
901*35238bceSAndroid Build Coastguard Worker                         };
902*35238bceSAndroid Build Coastguard Worker                         newDescriptorBindings.push_back(bCopy);
903*35238bceSAndroid Build Coastguard Worker                     }
904*35238bceSAndroid Build Coastguard Worker                     dsCI.second.pBindings = newDescriptorBindings.data();
905*35238bceSAndroid Build Coastguard Worker                 }
906*35238bceSAndroid Build Coastguard Worker 
907*35238bceSAndroid Build Coastguard Worker                 VkDescriptorSetLayout realDescriptorSetLayout;
908*35238bceSAndroid Build Coastguard Worker                 VK_CHECK(createDescriptorSetLayoutFunc(*pcDevice, &dsCI.second, DE_NULL, &realDescriptorSetLayout));
909*35238bceSAndroid Build Coastguard Worker                 falseToRealDescriptorSetLayouts.insert({dsCI.first, realDescriptorSetLayout});
910*35238bceSAndroid Build Coastguard Worker             }
911*35238bceSAndroid Build Coastguard Worker 
912*35238bceSAndroid Build Coastguard Worker             // decode pipeline layout structs and create VkPipelineLayouts. Requires creation of new pSetLayouts to bypass constness
913*35238bceSAndroid Build Coastguard Worker             for (auto &&pipelineLayout : input.pipelineLayouts)
914*35238bceSAndroid Build Coastguard Worker             {
915*35238bceSAndroid Build Coastguard Worker                 VkPipelineLayoutCreateInfo plCI{};
916*35238bceSAndroid Build Coastguard Worker                 readJSON_VkPipelineLayoutCreateInfo(jsonReader, pipelineLayout.second, plCI);
917*35238bceSAndroid Build Coastguard Worker                 // replace descriptor set layouts with real ones
918*35238bceSAndroid Build Coastguard Worker                 std::vector<VkDescriptorSetLayout> newSetLayouts;
919*35238bceSAndroid Build Coastguard Worker                 for (uint32_t i = 0; i < plCI.setLayoutCount; ++i)
920*35238bceSAndroid Build Coastguard Worker                 {
921*35238bceSAndroid Build Coastguard Worker                     auto jt = falseToRealDescriptorSetLayouts.find(plCI.pSetLayouts[i]);
922*35238bceSAndroid Build Coastguard Worker                     if (jt == end(falseToRealDescriptorSetLayouts))
923*35238bceSAndroid Build Coastguard Worker                         TCU_THROW(InternalError, "VkDescriptorSetLayout not found");
924*35238bceSAndroid Build Coastguard Worker                     newSetLayouts.push_back(jt->second);
925*35238bceSAndroid Build Coastguard Worker                 }
926*35238bceSAndroid Build Coastguard Worker                 plCI.pSetLayouts = newSetLayouts.data();
927*35238bceSAndroid Build Coastguard Worker 
928*35238bceSAndroid Build Coastguard Worker                 VkPipelineLayout realPipelineLayout;
929*35238bceSAndroid Build Coastguard Worker                 VK_CHECK(createPipelineLayoutFunc(*pcDevice, &plCI, DE_NULL, &realPipelineLayout));
930*35238bceSAndroid Build Coastguard Worker                 falseToRealPipelineLayouts.insert({pipelineLayout.first, realPipelineLayout});
931*35238bceSAndroid Build Coastguard Worker             }
932*35238bceSAndroid Build Coastguard Worker         }
933*35238bceSAndroid Build Coastguard Worker 
934*35238bceSAndroid Build Coastguard Worker         // after device creation - start creating pipelines
935*35238bceSAndroid Build Coastguard Worker         if (pipeline.pipelineContents.find("VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO") != std::string::npos)
936*35238bceSAndroid Build Coastguard Worker         {
937*35238bceSAndroid Build Coastguard Worker             VkGraphicsPipelineCreateInfo gpCI{};
938*35238bceSAndroid Build Coastguard Worker             gpCI.basePipelineHandle = VkPipeline(0);
939*35238bceSAndroid Build Coastguard Worker             readJSON_VkGraphicsPipelineCreateInfo(jsonReader, pipeline.pipelineContents, gpCI);
940*35238bceSAndroid Build Coastguard Worker 
941*35238bceSAndroid Build Coastguard Worker             // set poolEntrySize for pipeline
942*35238bceSAndroid Build Coastguard Worker             VkPipelineOfflineCreateInfo *offlineCreateInfo = (VkPipelineOfflineCreateInfo *)findStructureInChain(
943*35238bceSAndroid Build Coastguard Worker                 gpCI.pNext, VK_STRUCTURE_TYPE_PIPELINE_OFFLINE_CREATE_INFO);
944*35238bceSAndroid Build Coastguard Worker             if (offlineCreateInfo != DE_NULL)
945*35238bceSAndroid Build Coastguard Worker                 offlineCreateInfo->poolEntrySize = VKSC_DEFAULT_PIPELINE_POOL_SIZE;
946*35238bceSAndroid Build Coastguard Worker 
947*35238bceSAndroid Build Coastguard Worker             // replace VkShaderModules with real ones. Requires creation of new pStages to bypass constness
948*35238bceSAndroid Build Coastguard Worker             std::vector<VkPipelineShaderStageCreateInfo> newStages;
949*35238bceSAndroid Build Coastguard Worker             for (uint32_t i = 0; i < gpCI.stageCount; ++i)
950*35238bceSAndroid Build Coastguard Worker             {
951*35238bceSAndroid Build Coastguard Worker                 VkPipelineShaderStageCreateInfo newStage = gpCI.pStages[i];
952*35238bceSAndroid Build Coastguard Worker                 auto jt                                  = falseToRealShaderModules.find(gpCI.pStages[i].module);
953*35238bceSAndroid Build Coastguard Worker                 if (jt == end(falseToRealShaderModules))
954*35238bceSAndroid Build Coastguard Worker                     TCU_THROW(InternalError, "VkShaderModule not found");
955*35238bceSAndroid Build Coastguard Worker                 newStage.module = jt->second;
956*35238bceSAndroid Build Coastguard Worker                 newStages.push_back(newStage);
957*35238bceSAndroid Build Coastguard Worker             }
958*35238bceSAndroid Build Coastguard Worker             gpCI.pStages = newStages.data();
959*35238bceSAndroid Build Coastguard Worker 
960*35238bceSAndroid Build Coastguard Worker             // replace render pass with a real one
961*35238bceSAndroid Build Coastguard Worker             {
962*35238bceSAndroid Build Coastguard Worker                 auto jt = falseToRealRenderPasses.find(gpCI.renderPass);
963*35238bceSAndroid Build Coastguard Worker                 if (jt == end(falseToRealRenderPasses))
964*35238bceSAndroid Build Coastguard Worker                     TCU_THROW(InternalError, "VkRenderPass not found");
965*35238bceSAndroid Build Coastguard Worker                 gpCI.renderPass = jt->second;
966*35238bceSAndroid Build Coastguard Worker             }
967*35238bceSAndroid Build Coastguard Worker 
968*35238bceSAndroid Build Coastguard Worker             // replace pipeline layout with a real one
969*35238bceSAndroid Build Coastguard Worker             {
970*35238bceSAndroid Build Coastguard Worker                 auto jt = falseToRealPipelineLayouts.find(gpCI.layout);
971*35238bceSAndroid Build Coastguard Worker                 if (jt == end(falseToRealPipelineLayouts))
972*35238bceSAndroid Build Coastguard Worker                     TCU_THROW(InternalError, "VkPipelineLayout not found");
973*35238bceSAndroid Build Coastguard Worker                 gpCI.layout = jt->second;
974*35238bceSAndroid Build Coastguard Worker             }
975*35238bceSAndroid Build Coastguard Worker 
976*35238bceSAndroid Build Coastguard Worker             VkPipeline gPipeline(0u);
977*35238bceSAndroid Build Coastguard Worker             VK_CHECK(createGraphicsPipelinesFunc(*pcDevice, pipelineCache, 1, &gpCI, DE_NULL, &gPipeline));
978*35238bceSAndroid Build Coastguard Worker             // pipeline was added to cache. We may remove it immediately
979*35238bceSAndroid Build Coastguard Worker             destroyPipelineFunc(*pcDevice, gPipeline, DE_NULL);
980*35238bceSAndroid Build Coastguard Worker         }
981*35238bceSAndroid Build Coastguard Worker         else if (pipeline.pipelineContents.find("VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO") != std::string::npos)
982*35238bceSAndroid Build Coastguard Worker         {
983*35238bceSAndroid Build Coastguard Worker             VkComputePipelineCreateInfo cpCI{};
984*35238bceSAndroid Build Coastguard Worker             cpCI.basePipelineHandle = VkPipeline(0);
985*35238bceSAndroid Build Coastguard Worker             readJSON_VkComputePipelineCreateInfo(jsonReader, pipeline.pipelineContents, cpCI);
986*35238bceSAndroid Build Coastguard Worker 
987*35238bceSAndroid Build Coastguard Worker             // set poolEntrySize for pipeline
988*35238bceSAndroid Build Coastguard Worker             VkPipelineOfflineCreateInfo *offlineCreateInfo = (VkPipelineOfflineCreateInfo *)findStructureInChain(
989*35238bceSAndroid Build Coastguard Worker                 cpCI.pNext, VK_STRUCTURE_TYPE_PIPELINE_OFFLINE_CREATE_INFO);
990*35238bceSAndroid Build Coastguard Worker             if (offlineCreateInfo != DE_NULL)
991*35238bceSAndroid Build Coastguard Worker                 offlineCreateInfo->poolEntrySize = VKSC_DEFAULT_PIPELINE_POOL_SIZE;
992*35238bceSAndroid Build Coastguard Worker 
993*35238bceSAndroid Build Coastguard Worker             // replace VkShaderModule with real one
994*35238bceSAndroid Build Coastguard Worker             {
995*35238bceSAndroid Build Coastguard Worker                 auto jt = falseToRealShaderModules.find(cpCI.stage.module);
996*35238bceSAndroid Build Coastguard Worker                 if (jt == end(falseToRealShaderModules))
997*35238bceSAndroid Build Coastguard Worker                     TCU_THROW(InternalError, "VkShaderModule not found");
998*35238bceSAndroid Build Coastguard Worker                 cpCI.stage.module = jt->second;
999*35238bceSAndroid Build Coastguard Worker             }
1000*35238bceSAndroid Build Coastguard Worker 
1001*35238bceSAndroid Build Coastguard Worker             // replace pipeline layout with a real one
1002*35238bceSAndroid Build Coastguard Worker             {
1003*35238bceSAndroid Build Coastguard Worker                 auto jt = falseToRealPipelineLayouts.find(cpCI.layout);
1004*35238bceSAndroid Build Coastguard Worker                 if (jt == end(falseToRealPipelineLayouts))
1005*35238bceSAndroid Build Coastguard Worker                     TCU_THROW(InternalError, "VkPipelineLayout not found");
1006*35238bceSAndroid Build Coastguard Worker                 cpCI.layout = jt->second;
1007*35238bceSAndroid Build Coastguard Worker             }
1008*35238bceSAndroid Build Coastguard Worker 
1009*35238bceSAndroid Build Coastguard Worker             VkPipeline cPipeline(0u);
1010*35238bceSAndroid Build Coastguard Worker             VK_CHECK(createComputePipelinesFunc(*pcDevice, pipelineCache, 1, &cpCI, DE_NULL, &cPipeline));
1011*35238bceSAndroid Build Coastguard Worker             // pipeline was added to cache. We may remove it immediately
1012*35238bceSAndroid Build Coastguard Worker             destroyPipelineFunc(*pcDevice, cPipeline, DE_NULL);
1013*35238bceSAndroid Build Coastguard Worker         }
1014*35238bceSAndroid Build Coastguard Worker         else
1015*35238bceSAndroid Build Coastguard Worker             TCU_THROW(InternalError, "Could not recognize pipeline type");
1016*35238bceSAndroid Build Coastguard Worker     }
1017*35238bceSAndroid Build Coastguard Worker 
1018*35238bceSAndroid Build Coastguard Worker     if (pcDevice.get() != DE_NULL)
1019*35238bceSAndroid Build Coastguard Worker     {
1020*35238bceSAndroid Build Coastguard Worker         // getPipelineCacheData() binary data, store it in m_cacheData
1021*35238bceSAndroid Build Coastguard Worker         std::size_t cacheSize;
1022*35238bceSAndroid Build Coastguard Worker         VK_CHECK(getPipelineCacheDataFunc(*pcDevice, pipelineCache, &cacheSize, DE_NULL));
1023*35238bceSAndroid Build Coastguard Worker         resultCacheData.resize(cacheSize);
1024*35238bceSAndroid Build Coastguard Worker         VK_CHECK(getPipelineCacheDataFunc(*pcDevice, pipelineCache, &cacheSize, resultCacheData.data()));
1025*35238bceSAndroid Build Coastguard Worker 
1026*35238bceSAndroid Build Coastguard Worker         // clean up resources - in ResourceInterfaceStandard we just simulate Vulkan SC driver after all...
1027*35238bceSAndroid Build Coastguard Worker         for (auto &&it : falseToRealPipelineLayouts)
1028*35238bceSAndroid Build Coastguard Worker             destroyPipelineLayoutFunc(*pcDevice, it.second, DE_NULL);
1029*35238bceSAndroid Build Coastguard Worker         for (auto &&it : falseToRealDescriptorSetLayouts)
1030*35238bceSAndroid Build Coastguard Worker             destroyDescriptorSetLayoutFunc(*pcDevice, it.second, DE_NULL);
1031*35238bceSAndroid Build Coastguard Worker         for (auto &&it : falseToRealRenderPasses)
1032*35238bceSAndroid Build Coastguard Worker             destroyRenderPassFunc(*pcDevice, it.second, DE_NULL);
1033*35238bceSAndroid Build Coastguard Worker         for (auto &&it : falseToRealShaderModules)
1034*35238bceSAndroid Build Coastguard Worker             destroyShaderModuleFunc(*pcDevice, it.second, DE_NULL);
1035*35238bceSAndroid Build Coastguard Worker         for (auto &&it : falseToRealSamplers)
1036*35238bceSAndroid Build Coastguard Worker             destroySamplerFunc(*pcDevice, it.second, DE_NULL);
1037*35238bceSAndroid Build Coastguard Worker         for (auto &&it : falseToRealSamplerYcbcrConversions)
1038*35238bceSAndroid Build Coastguard Worker             destroySamplerYcbcrConversionFunc(*pcDevice, it.second, DE_NULL);
1039*35238bceSAndroid Build Coastguard Worker 
1040*35238bceSAndroid Build Coastguard Worker         destroyPipelineCacheFunc(*pcDevice, pipelineCache, DE_NULL);
1041*35238bceSAndroid Build Coastguard Worker     }
1042*35238bceSAndroid Build Coastguard Worker 
1043*35238bceSAndroid Build Coastguard Worker     return resultCacheData;
1044*35238bceSAndroid Build Coastguard Worker }
1045*35238bceSAndroid Build Coastguard Worker 
extractSizesFromPipelineCache(const VulkanPipelineCacheInput & input,const vector<u8> & pipelineCache,uint32_t pipelineDefaultSize,bool recyclePipelineMemory)1046*35238bceSAndroid Build Coastguard Worker std::vector<VulkanPipelineSize> extractSizesFromPipelineCache(const VulkanPipelineCacheInput &input,
1047*35238bceSAndroid Build Coastguard Worker                                                               const vector<u8> &pipelineCache,
1048*35238bceSAndroid Build Coastguard Worker                                                               uint32_t pipelineDefaultSize, bool recyclePipelineMemory)
1049*35238bceSAndroid Build Coastguard Worker {
1050*35238bceSAndroid Build Coastguard Worker     std::vector<VulkanPipelineSize> result;
1051*35238bceSAndroid Build Coastguard Worker     if (input.pipelines.empty())
1052*35238bceSAndroid Build Coastguard Worker         return result;
1053*35238bceSAndroid Build Coastguard Worker     VKSCPipelineCacheHeaderReader pcr(pipelineCache.size(), pipelineCache.data());
1054*35238bceSAndroid Build Coastguard Worker     if (pcr.isValid())
1055*35238bceSAndroid Build Coastguard Worker     {
1056*35238bceSAndroid Build Coastguard Worker         for (uint32_t p = 0; p < pcr.getPipelineIndexCount(); ++p)
1057*35238bceSAndroid Build Coastguard Worker         {
1058*35238bceSAndroid Build Coastguard Worker             const VkPipelineCacheSafetyCriticalIndexEntry *pie = pcr.getPipelineIndexEntry(p);
1059*35238bceSAndroid Build Coastguard Worker             if (nullptr != pie)
1060*35238bceSAndroid Build Coastguard Worker             {
1061*35238bceSAndroid Build Coastguard Worker                 VulkanPipelineSize pipelineSize;
1062*35238bceSAndroid Build Coastguard Worker                 pipelineSize.id = resetPipelineOfflineCreateInfo();
1063*35238bceSAndroid Build Coastguard Worker                 for (uint32_t i = 0; i < VK_UUID_SIZE; ++i)
1064*35238bceSAndroid Build Coastguard Worker                     pipelineSize.id.pipelineIdentifier[i] = pie->pipelineIdentifier[i];
1065*35238bceSAndroid Build Coastguard Worker                 pipelineSize.size  = uint32_t(pie->pipelineMemorySize);
1066*35238bceSAndroid Build Coastguard Worker                 pipelineSize.count = 0u;
1067*35238bceSAndroid Build Coastguard Worker                 auto it            = std::find_if(begin(input.pipelines), end(input.pipelines),
1068*35238bceSAndroid Build Coastguard Worker                                                   vksc_server::PipelineIdentifierEqual(pipelineSize.id));
1069*35238bceSAndroid Build Coastguard Worker                 if (it != end(input.pipelines))
1070*35238bceSAndroid Build Coastguard Worker                 {
1071*35238bceSAndroid Build Coastguard Worker                     if (recyclePipelineMemory)
1072*35238bceSAndroid Build Coastguard Worker                         pipelineSize.count = it->maxCount;
1073*35238bceSAndroid Build Coastguard Worker                     else // you'd better have enough memory...
1074*35238bceSAndroid Build Coastguard Worker                         pipelineSize.count = it->allCount;
1075*35238bceSAndroid Build Coastguard Worker                 }
1076*35238bceSAndroid Build Coastguard Worker                 result.emplace_back(pipelineSize);
1077*35238bceSAndroid Build Coastguard Worker             }
1078*35238bceSAndroid Build Coastguard Worker         }
1079*35238bceSAndroid Build Coastguard Worker     }
1080*35238bceSAndroid Build Coastguard Worker     else // ordinary Vulkan pipeline. Declare all pipeline sizes as equal to pipelineDefaultSize
1081*35238bceSAndroid Build Coastguard Worker     {
1082*35238bceSAndroid Build Coastguard Worker         for (uint32_t p = 0; p < input.pipelines.size(); ++p)
1083*35238bceSAndroid Build Coastguard Worker         {
1084*35238bceSAndroid Build Coastguard Worker             VulkanPipelineSize pipelineSize;
1085*35238bceSAndroid Build Coastguard Worker             pipelineSize.id = resetPipelineOfflineCreateInfo();
1086*35238bceSAndroid Build Coastguard Worker             for (uint32_t i = 0; i < VK_UUID_SIZE; ++i)
1087*35238bceSAndroid Build Coastguard Worker                 pipelineSize.id.pipelineIdentifier[i] = input.pipelines[p].id.pipelineIdentifier[i];
1088*35238bceSAndroid Build Coastguard Worker             pipelineSize.size = pipelineDefaultSize;
1089*35238bceSAndroid Build Coastguard Worker             if (recyclePipelineMemory)
1090*35238bceSAndroid Build Coastguard Worker                 pipelineSize.count = input.pipelines[p].maxCount;
1091*35238bceSAndroid Build Coastguard Worker             else // you'd better have enough memory...
1092*35238bceSAndroid Build Coastguard Worker                 pipelineSize.count = input.pipelines[p].allCount;
1093*35238bceSAndroid Build Coastguard Worker             result.emplace_back(pipelineSize);
1094*35238bceSAndroid Build Coastguard Worker         }
1095*35238bceSAndroid Build Coastguard Worker     }
1096*35238bceSAndroid Build Coastguard Worker 
1097*35238bceSAndroid Build Coastguard Worker     return result;
1098*35238bceSAndroid Build Coastguard Worker }
1099*35238bceSAndroid Build Coastguard Worker 
1100*35238bceSAndroid Build Coastguard Worker } // namespace vksc_server
1101