• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2024 The Khronos Group Inc.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief Utilities for pipeline binaries.
22  *//*--------------------------------------------------------------------*/
23 
24 #include "vkPipelineBinaryUtil.hpp"
25 #include "vkQueryUtil.hpp"
26 #include "deSTLUtil.hpp"
27 #include <vector>
28 
29 #ifndef CTS_USES_VULKANSC
30 
31 namespace vk
32 {
33 
makeMovablePipelineBinary(const DeviceInterface & vk,const VkDevice device,VkPipelineBinaryKHR rawPipelineBinary)34 Move<VkPipelineBinaryKHR> makeMovablePipelineBinary(const DeviceInterface &vk, const VkDevice device,
35                                                     VkPipelineBinaryKHR rawPipelineBinary)
36 {
37     return Move<VkPipelineBinaryKHR>(check<VkPipelineBinaryKHR>(rawPipelineBinary),
38                                      Deleter<VkPipelineBinaryKHR>(vk, device, DE_NULL));
39 }
40 
PipelineBinaryWrapper(const DeviceInterface & vk,const VkDevice device)41 PipelineBinaryWrapper::PipelineBinaryWrapper(const DeviceInterface &vk, const VkDevice device)
42     : m_vk(vk)
43     , m_device(device)
44 {
45 }
46 
getPipelineKey(const void * pPipelineCreateInfo) const47 VkPipelineBinaryKeyKHR PipelineBinaryWrapper::getPipelineKey(const void *pPipelineCreateInfo) const
48 {
49     VkPipelineBinaryKeyKHR pipelineKey         = initVulkanStructure();
50     VkPipelineCreateInfoKHR pipelineCreateInfo = initVulkanStructure(const_cast<void *>(pPipelineCreateInfo));
51 
52     VK_CHECK(m_vk.getPipelineKeyKHR(m_device, &pipelineCreateInfo, &pipelineKey));
53 
54     return pipelineKey;
55 }
56 
createPipelineBinariesFromPipeline(VkPipeline pipeline)57 VkResult PipelineBinaryWrapper::createPipelineBinariesFromPipeline(VkPipeline pipeline)
58 {
59     VkPipelineBinaryCreateInfoKHR pipelineBinaryCreateInfo = initVulkanStructure();
60     pipelineBinaryCreateInfo.pipeline                      = pipeline;
61 
62     return createPipelineBinariesFromCreateInfo(pipelineBinaryCreateInfo);
63 }
64 
createPipelineBinariesFromInternalCache(const void * pPipelineCreateInfo)65 VkResult PipelineBinaryWrapper::createPipelineBinariesFromInternalCache(const void *pPipelineCreateInfo)
66 {
67     VkPipelineCreateInfoKHR pipelineCreateInfo = initVulkanStructure();
68     pipelineCreateInfo.pNext                   = const_cast<void *>(pPipelineCreateInfo);
69 
70     VkPipelineBinaryCreateInfoKHR pipelineBinaryCreateInfo = initVulkanStructure();
71     pipelineBinaryCreateInfo.pPipelineCreateInfo           = &pipelineCreateInfo;
72 
73     return createPipelineBinariesFromCreateInfo(pipelineBinaryCreateInfo);
74 }
75 
createPipelineBinariesFromBinaryData(const std::vector<VkPipelineBinaryDataKHR> & pipelineDataInfo)76 VkResult PipelineBinaryWrapper::createPipelineBinariesFromBinaryData(
77     const std::vector<VkPipelineBinaryDataKHR> &pipelineDataInfo)
78 {
79     // for graphics pipeline libraries not all pipeline stages have to have binaries
80     std::size_t keyCount = m_binaryKeys.size();
81     if (keyCount == 0)
82         return VK_SUCCESS;
83 
84     VkPipelineBinaryKeysAndDataKHR binaryKeysAndData{
85         (uint32_t)keyCount,     // uint32_t binaryCount;
86         m_binaryKeys.data(),    // const VkPipelineBinaryKeyKHR* pPipelineBinaryKeys;
87         pipelineDataInfo.data() // const VkPipelineBinaryDataKHR* pPipelineBinaryData;
88     };
89     VkPipelineBinaryCreateInfoKHR pipelineBinaryCreateInfo = initVulkanStructure();
90     pipelineBinaryCreateInfo.pKeysAndDataInfo              = &binaryKeysAndData;
91 
92     return createPipelineBinariesFromCreateInfo(pipelineBinaryCreateInfo);
93 }
94 
createPipelineBinariesFromCreateInfo(const VkPipelineBinaryCreateInfoKHR & createInfos)95 VkResult PipelineBinaryWrapper::createPipelineBinariesFromCreateInfo(const VkPipelineBinaryCreateInfoKHR &createInfos)
96 {
97     // check how many binaries will be created
98     VkPipelineBinaryHandlesInfoKHR binaryHandlesInfo = initVulkanStructure();
99     VkResult result = m_vk.createPipelineBinariesKHR(m_device, &createInfos, NULL, &binaryHandlesInfo);
100     if (result != VK_SUCCESS)
101         return result;
102 
103     // create pipeline binary objects
104     std::size_t binaryCount = binaryHandlesInfo.pipelineBinaryCount;
105     m_binariesRaw.resize(binaryCount);
106     binaryHandlesInfo.pPipelineBinaries = m_binariesRaw.data();
107     result = m_vk.createPipelineBinariesKHR(m_device, &createInfos, DE_NULL, &binaryHandlesInfo);
108     if (result != VK_SUCCESS)
109         return result;
110 
111     // wrap pipeline binaries to movable references to avoid leaks
112     m_binaries.resize(binaryCount);
113     for (std::size_t i = 0; i < binaryCount; ++i)
114         m_binaries[i] = makeMovablePipelineBinary(m_vk, m_device, m_binariesRaw[i]);
115 
116     return result;
117 }
118 
getPipelineBinaryData(std::vector<VkPipelineBinaryDataKHR> & pipelineDataInfo,std::vector<std::vector<uint8_t>> & pipelineDataBlob)119 void PipelineBinaryWrapper::getPipelineBinaryData(std::vector<VkPipelineBinaryDataKHR> &pipelineDataInfo,
120                                                   std::vector<std::vector<uint8_t>> &pipelineDataBlob)
121 {
122     // for graphics pipeline libraries not all pipeline stages have to have binaries
123     const std::size_t binaryCount = m_binariesRaw.size();
124     if (binaryCount == 0)
125         return;
126 
127     m_binaryKeys.resize(binaryCount);
128     pipelineDataInfo.resize(binaryCount);
129     pipelineDataBlob.resize(binaryCount);
130 
131     for (std::size_t i = 0; i < binaryCount; ++i)
132     {
133         VkPipelineBinaryDataInfoKHR binaryInfo = initVulkanStructure();
134         binaryInfo.pipelineBinary              = m_binariesRaw[i];
135 
136         // get binary key and data size
137         size_t binaryDataSize = 0;
138         m_binaryKeys[i]       = initVulkanStructure();
139         VK_CHECK(m_vk.getPipelineBinaryDataKHR(m_device, &binaryInfo, &m_binaryKeys[i], &binaryDataSize, NULL));
140         DE_ASSERT(binaryDataSize > 0);
141 
142         pipelineDataInfo[i].dataSize = binaryDataSize;
143         pipelineDataBlob[i].resize(binaryDataSize);
144         pipelineDataInfo[i].pData = pipelineDataBlob[i].data();
145 
146         // get binary data
147         VK_CHECK(m_vk.getPipelineBinaryDataKHR(m_device, &binaryInfo, &m_binaryKeys[i], &binaryDataSize,
148                                                pipelineDataBlob[i].data()));
149     }
150 }
151 
deletePipelineBinariesAndKeys(void)152 void PipelineBinaryWrapper::deletePipelineBinariesAndKeys(void)
153 {
154     m_binaryKeys.clear();
155     m_binaries.clear();
156     m_binariesRaw.clear();
157 }
158 
deletePipelineBinariesKeepKeys(void)159 void PipelineBinaryWrapper::deletePipelineBinariesKeepKeys(void)
160 {
161     m_binaries.clear();
162     m_binariesRaw.clear();
163 }
164 
preparePipelineBinaryInfo(void) const165 VkPipelineBinaryInfoKHR PipelineBinaryWrapper::preparePipelineBinaryInfo(void) const
166 {
167     const std::size_t binaryCount = m_binariesRaw.size();
168 
169     return {
170         VK_STRUCTURE_TYPE_PIPELINE_BINARY_INFO_KHR, DE_NULL,
171         static_cast<uint32_t>(binaryCount), // uint32_t binaryCount;
172         de::dataOrNull(m_binariesRaw)       // const VkPipelineBinaryKHR* pPipelineBinaries;
173     };
174 }
175 
getKeyCount() const176 uint32_t PipelineBinaryWrapper::getKeyCount() const
177 {
178     return static_cast<uint32_t>(m_binaryKeys.size());
179 }
180 
getBinariesCount() const181 uint32_t PipelineBinaryWrapper::getBinariesCount() const
182 {
183     return static_cast<uint32_t>(m_binariesRaw.size());
184 }
185 
getBinaryKeys() const186 const VkPipelineBinaryKeyKHR *PipelineBinaryWrapper::getBinaryKeys() const
187 {
188     return m_binaryKeys.data();
189 }
190 
getPipelineBinaries() const191 const VkPipelineBinaryKHR *PipelineBinaryWrapper::getPipelineBinaries() const
192 {
193     return m_binariesRaw.data();
194 }
195 
196 } // namespace vk
197 
198 #endif
199