• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2019 The SwiftShader Authors. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //    http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "VkDeviceMemory.hpp"
16 
17 #include "System/Debug.hpp"
18 #include "System/Linux/MemFd.hpp"
19 
20 #include <errno.h>
21 #include <string.h>
22 #include <sys/mman.h>
23 
24 class OpaqueFdExternalMemory : public vk::DeviceMemory, public vk::ObjectBase<OpaqueFdExternalMemory, VkDeviceMemory>
25 {
26 public:
27 	static const VkExternalMemoryHandleTypeFlagBits typeFlagBit = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT;
28 
SupportsAllocateInfo(const vk::DeviceMemory::ExtendedAllocationInfo & extendedAllocationInfo)29 	static bool SupportsAllocateInfo(const vk::DeviceMemory::ExtendedAllocationInfo &extendedAllocationInfo)
30 	{
31 		OpaqueFdAllocateInfo info(extendedAllocationInfo);
32 		return info.importFd || info.exportFd;
33 	}
34 
OpaqueFdExternalMemory(const VkMemoryAllocateInfo * pCreateInfo,void * mem,const vk::DeviceMemory::ExtendedAllocationInfo & extendedAllocationInfo,vk::Device * pDevice)35 	explicit OpaqueFdExternalMemory(const VkMemoryAllocateInfo *pCreateInfo, void *mem, const vk::DeviceMemory::ExtendedAllocationInfo &extendedAllocationInfo, vk::Device *pDevice)
36 	    : vk::DeviceMemory(pCreateInfo, pDevice)
37 	    , allocateInfo(extendedAllocationInfo)
38 	{
39 	}
40 
~OpaqueFdExternalMemory()41 	~OpaqueFdExternalMemory()
42 	{
43 		memfd.close();
44 	}
45 
allocateBuffer()46 	VkResult allocateBuffer() override
47 	{
48 		if(allocateInfo.importFd)
49 		{
50 			memfd.importFd(allocateInfo.fd);
51 			if(!memfd.isValid())
52 			{
53 				return VK_ERROR_INVALID_EXTERNAL_HANDLE;
54 			}
55 		}
56 		else
57 		{
58 			ASSERT(allocateInfo.exportFd);
59 			static int counter = 0;
60 			char name[40];
61 			snprintf(name, sizeof(name), "SwiftShader.Memory.%d", ++counter);
62 			if(!memfd.allocate(name, allocationSize))
63 			{
64 				TRACE("memfd.allocate() returned %s", strerror(errno));
65 				return VK_ERROR_OUT_OF_DEVICE_MEMORY;
66 			}
67 		}
68 		void *addr = memfd.mapReadWrite(0, allocationSize);
69 		if(!addr)
70 		{
71 			return VK_ERROR_MEMORY_MAP_FAILED;
72 		}
73 		buffer = addr;
74 		return VK_SUCCESS;
75 	}
76 
freeBuffer()77 	void freeBuffer() override
78 	{
79 		memfd.unmap(buffer, allocationSize);
80 	}
81 
getFlagBit() const82 	VkExternalMemoryHandleTypeFlagBits getFlagBit() const override
83 	{
84 		return typeFlagBit;
85 	}
86 
exportFd(int * pFd) const87 	VkResult exportFd(int *pFd) const override
88 	{
89 		int fd = memfd.exportFd();
90 		if(fd < 0)
91 		{
92 			return VK_ERROR_INVALID_EXTERNAL_HANDLE;
93 		}
94 		*pFd = fd;
95 		return VK_SUCCESS;
96 	}
97 
98 private:
99 	LinuxMemFd memfd;
100 	OpaqueFdAllocateInfo allocateInfo;
101 };
102