xref: /aosp_15_r20/external/swiftshader/src/Vulkan/VkPipelineCache.cpp (revision 03ce13f70fcc45d86ee91b7ee4cab1936a95046e)
1*03ce13f7SAndroid Build Coastguard Worker // Copyright 2019 The SwiftShader Authors. All Rights Reserved.
2*03ce13f7SAndroid Build Coastguard Worker //
3*03ce13f7SAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
4*03ce13f7SAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
5*03ce13f7SAndroid Build Coastguard Worker // You may obtain a copy of the License at
6*03ce13f7SAndroid Build Coastguard Worker //
7*03ce13f7SAndroid Build Coastguard Worker //    http://www.apache.org/licenses/LICENSE-2.0
8*03ce13f7SAndroid Build Coastguard Worker //
9*03ce13f7SAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*03ce13f7SAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
11*03ce13f7SAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*03ce13f7SAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
13*03ce13f7SAndroid Build Coastguard Worker // limitations under the License.
14*03ce13f7SAndroid Build Coastguard Worker 
15*03ce13f7SAndroid Build Coastguard Worker #include "VkPipelineCache.hpp"
16*03ce13f7SAndroid Build Coastguard Worker 
17*03ce13f7SAndroid Build Coastguard Worker #include <cstring>
18*03ce13f7SAndroid Build Coastguard Worker 
19*03ce13f7SAndroid Build Coastguard Worker namespace vk {
20*03ce13f7SAndroid Build Coastguard Worker 
SpirvBinaryKey(const sw::SpirvBinary & spirv,const VkSpecializationInfo * specializationInfo,bool robustBufferAccess,bool optimize)21*03ce13f7SAndroid Build Coastguard Worker PipelineCache::SpirvBinaryKey::SpirvBinaryKey(const sw::SpirvBinary &spirv,
22*03ce13f7SAndroid Build Coastguard Worker                                               const VkSpecializationInfo *specializationInfo,
23*03ce13f7SAndroid Build Coastguard Worker                                               bool robustBufferAccess,
24*03ce13f7SAndroid Build Coastguard Worker                                               bool optimize)
25*03ce13f7SAndroid Build Coastguard Worker     : spirv(spirv)
26*03ce13f7SAndroid Build Coastguard Worker     , specializationInfo(specializationInfo)
27*03ce13f7SAndroid Build Coastguard Worker     , robustBufferAccess(robustBufferAccess)
28*03ce13f7SAndroid Build Coastguard Worker     , optimize(optimize)
29*03ce13f7SAndroid Build Coastguard Worker {
30*03ce13f7SAndroid Build Coastguard Worker }
31*03ce13f7SAndroid Build Coastguard Worker 
operator <(const SpirvBinaryKey & other) const32*03ce13f7SAndroid Build Coastguard Worker bool PipelineCache::SpirvBinaryKey::operator<(const SpirvBinaryKey &other) const
33*03ce13f7SAndroid Build Coastguard Worker {
34*03ce13f7SAndroid Build Coastguard Worker 	if(spirv.size() != other.spirv.size())
35*03ce13f7SAndroid Build Coastguard Worker 	{
36*03ce13f7SAndroid Build Coastguard Worker 		return spirv.size() < other.spirv.size();
37*03ce13f7SAndroid Build Coastguard Worker 	}
38*03ce13f7SAndroid Build Coastguard Worker 
39*03ce13f7SAndroid Build Coastguard Worker 	int cmp = memcmp(spirv.data(), other.spirv.data(), spirv.size() * sizeof(uint32_t));
40*03ce13f7SAndroid Build Coastguard Worker 	if(cmp != 0)
41*03ce13f7SAndroid Build Coastguard Worker 	{
42*03ce13f7SAndroid Build Coastguard Worker 		return cmp < 0;
43*03ce13f7SAndroid Build Coastguard Worker 	}
44*03ce13f7SAndroid Build Coastguard Worker 
45*03ce13f7SAndroid Build Coastguard Worker 	if(robustBufferAccess != other.robustBufferAccess)
46*03ce13f7SAndroid Build Coastguard Worker 	{
47*03ce13f7SAndroid Build Coastguard Worker 		return !robustBufferAccess && other.robustBufferAccess;
48*03ce13f7SAndroid Build Coastguard Worker 	}
49*03ce13f7SAndroid Build Coastguard Worker 
50*03ce13f7SAndroid Build Coastguard Worker 	if(optimize != other.optimize)
51*03ce13f7SAndroid Build Coastguard Worker 	{
52*03ce13f7SAndroid Build Coastguard Worker 		return !optimize && other.optimize;
53*03ce13f7SAndroid Build Coastguard Worker 	}
54*03ce13f7SAndroid Build Coastguard Worker 
55*03ce13f7SAndroid Build Coastguard Worker 	return (specializationInfo < other.specializationInfo);
56*03ce13f7SAndroid Build Coastguard Worker }
57*03ce13f7SAndroid Build Coastguard Worker 
ComputeProgramKey(uint64_t shaderIdentifier,uint32_t pipelineLayoutIdentifier)58*03ce13f7SAndroid Build Coastguard Worker PipelineCache::ComputeProgramKey::ComputeProgramKey(uint64_t shaderIdentifier, uint32_t pipelineLayoutIdentifier)
59*03ce13f7SAndroid Build Coastguard Worker     : shaderIdentifier(shaderIdentifier)
60*03ce13f7SAndroid Build Coastguard Worker     , pipelineLayoutIdentifier(pipelineLayoutIdentifier)
61*03ce13f7SAndroid Build Coastguard Worker {}
62*03ce13f7SAndroid Build Coastguard Worker 
operator <(const ComputeProgramKey & other) const63*03ce13f7SAndroid Build Coastguard Worker bool PipelineCache::ComputeProgramKey::operator<(const ComputeProgramKey &other) const
64*03ce13f7SAndroid Build Coastguard Worker {
65*03ce13f7SAndroid Build Coastguard Worker 	return std::tie(shaderIdentifier, pipelineLayoutIdentifier) < std::tie(other.shaderIdentifier, other.pipelineLayoutIdentifier);
66*03ce13f7SAndroid Build Coastguard Worker }
67*03ce13f7SAndroid Build Coastguard Worker 
PipelineCache(const VkPipelineCacheCreateInfo * pCreateInfo,void * mem)68*03ce13f7SAndroid Build Coastguard Worker PipelineCache::PipelineCache(const VkPipelineCacheCreateInfo *pCreateInfo, void *mem)
69*03ce13f7SAndroid Build Coastguard Worker     : dataSize(ComputeRequiredAllocationSize(pCreateInfo))
70*03ce13f7SAndroid Build Coastguard Worker     , data(reinterpret_cast<uint8_t *>(mem))
71*03ce13f7SAndroid Build Coastguard Worker {
72*03ce13f7SAndroid Build Coastguard Worker 	CacheHeader *header = reinterpret_cast<CacheHeader *>(mem);
73*03ce13f7SAndroid Build Coastguard Worker 	header->headerLength = sizeof(CacheHeader);
74*03ce13f7SAndroid Build Coastguard Worker 	header->headerVersion = VK_PIPELINE_CACHE_HEADER_VERSION_ONE;
75*03ce13f7SAndroid Build Coastguard Worker 	header->vendorID = VENDOR_ID;
76*03ce13f7SAndroid Build Coastguard Worker 	header->deviceID = DEVICE_ID;
77*03ce13f7SAndroid Build Coastguard Worker 	memcpy(header->pipelineCacheUUID, SWIFTSHADER_UUID, VK_UUID_SIZE);
78*03ce13f7SAndroid Build Coastguard Worker 
79*03ce13f7SAndroid Build Coastguard Worker 	if(pCreateInfo->pInitialData && (pCreateInfo->initialDataSize > 0))
80*03ce13f7SAndroid Build Coastguard Worker 	{
81*03ce13f7SAndroid Build Coastguard Worker 		memcpy(data + sizeof(CacheHeader), pCreateInfo->pInitialData, pCreateInfo->initialDataSize);
82*03ce13f7SAndroid Build Coastguard Worker 	}
83*03ce13f7SAndroid Build Coastguard Worker }
84*03ce13f7SAndroid Build Coastguard Worker 
~PipelineCache()85*03ce13f7SAndroid Build Coastguard Worker PipelineCache::~PipelineCache()
86*03ce13f7SAndroid Build Coastguard Worker {
87*03ce13f7SAndroid Build Coastguard Worker 	spirvShaders.clear();
88*03ce13f7SAndroid Build Coastguard Worker 	computePrograms.clear();
89*03ce13f7SAndroid Build Coastguard Worker }
90*03ce13f7SAndroid Build Coastguard Worker 
destroy(const VkAllocationCallbacks * pAllocator)91*03ce13f7SAndroid Build Coastguard Worker void PipelineCache::destroy(const VkAllocationCallbacks *pAllocator)
92*03ce13f7SAndroid Build Coastguard Worker {
93*03ce13f7SAndroid Build Coastguard Worker 	vk::freeHostMemory(data, pAllocator);
94*03ce13f7SAndroid Build Coastguard Worker }
95*03ce13f7SAndroid Build Coastguard Worker 
ComputeRequiredAllocationSize(const VkPipelineCacheCreateInfo * pCreateInfo)96*03ce13f7SAndroid Build Coastguard Worker size_t PipelineCache::ComputeRequiredAllocationSize(const VkPipelineCacheCreateInfo *pCreateInfo)
97*03ce13f7SAndroid Build Coastguard Worker {
98*03ce13f7SAndroid Build Coastguard Worker 	return pCreateInfo->initialDataSize + sizeof(CacheHeader);
99*03ce13f7SAndroid Build Coastguard Worker }
100*03ce13f7SAndroid Build Coastguard Worker 
getData(size_t * pDataSize,void * pData)101*03ce13f7SAndroid Build Coastguard Worker VkResult PipelineCache::getData(size_t *pDataSize, void *pData)
102*03ce13f7SAndroid Build Coastguard Worker {
103*03ce13f7SAndroid Build Coastguard Worker 	if(!pData)
104*03ce13f7SAndroid Build Coastguard Worker 	{
105*03ce13f7SAndroid Build Coastguard Worker 		*pDataSize = dataSize;
106*03ce13f7SAndroid Build Coastguard Worker 		return VK_SUCCESS;
107*03ce13f7SAndroid Build Coastguard Worker 	}
108*03ce13f7SAndroid Build Coastguard Worker 
109*03ce13f7SAndroid Build Coastguard Worker 	if(*pDataSize != dataSize)
110*03ce13f7SAndroid Build Coastguard Worker 	{
111*03ce13f7SAndroid Build Coastguard Worker 		*pDataSize = 0;
112*03ce13f7SAndroid Build Coastguard Worker 		return VK_INCOMPLETE;
113*03ce13f7SAndroid Build Coastguard Worker 	}
114*03ce13f7SAndroid Build Coastguard Worker 
115*03ce13f7SAndroid Build Coastguard Worker 	if(*pDataSize > 0)
116*03ce13f7SAndroid Build Coastguard Worker 	{
117*03ce13f7SAndroid Build Coastguard Worker 		memcpy(pData, data, *pDataSize);
118*03ce13f7SAndroid Build Coastguard Worker 	}
119*03ce13f7SAndroid Build Coastguard Worker 
120*03ce13f7SAndroid Build Coastguard Worker 	return VK_SUCCESS;
121*03ce13f7SAndroid Build Coastguard Worker }
122*03ce13f7SAndroid Build Coastguard Worker 
merge(uint32_t srcCacheCount,const VkPipelineCache * pSrcCaches)123*03ce13f7SAndroid Build Coastguard Worker VkResult PipelineCache::merge(uint32_t srcCacheCount, const VkPipelineCache *pSrcCaches)
124*03ce13f7SAndroid Build Coastguard Worker {
125*03ce13f7SAndroid Build Coastguard Worker 	for(uint32_t i = 0; i < srcCacheCount; i++)
126*03ce13f7SAndroid Build Coastguard Worker 	{
127*03ce13f7SAndroid Build Coastguard Worker 		PipelineCache *srcCache = Cast(pSrcCaches[i]);
128*03ce13f7SAndroid Build Coastguard Worker 
129*03ce13f7SAndroid Build Coastguard Worker 		{
130*03ce13f7SAndroid Build Coastguard Worker 			marl::lock thisLock(spirvShadersMutex);
131*03ce13f7SAndroid Build Coastguard Worker 			marl::lock srcLock(srcCache->spirvShadersMutex);
132*03ce13f7SAndroid Build Coastguard Worker 			spirvShaders.insert(srcCache->spirvShaders.begin(), srcCache->spirvShaders.end());
133*03ce13f7SAndroid Build Coastguard Worker 		}
134*03ce13f7SAndroid Build Coastguard Worker 
135*03ce13f7SAndroid Build Coastguard Worker 		{
136*03ce13f7SAndroid Build Coastguard Worker 			marl::lock thisLock(computeProgramsMutex);
137*03ce13f7SAndroid Build Coastguard Worker 			marl::lock srcLock(srcCache->computeProgramsMutex);
138*03ce13f7SAndroid Build Coastguard Worker 			computePrograms.insert(srcCache->computePrograms.begin(), srcCache->computePrograms.end());
139*03ce13f7SAndroid Build Coastguard Worker 		}
140*03ce13f7SAndroid Build Coastguard Worker 	}
141*03ce13f7SAndroid Build Coastguard Worker 
142*03ce13f7SAndroid Build Coastguard Worker 	return VK_SUCCESS;
143*03ce13f7SAndroid Build Coastguard Worker }
144*03ce13f7SAndroid Build Coastguard Worker 
145*03ce13f7SAndroid Build Coastguard Worker }  // namespace vk
146