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 "VkDeviceMemory.hpp" 16*03ce13f7SAndroid Build Coastguard Worker 17*03ce13f7SAndroid Build Coastguard Worker #include "System/Debug.hpp" 18*03ce13f7SAndroid Build Coastguard Worker #include "System/Linux/MemFd.hpp" 19*03ce13f7SAndroid Build Coastguard Worker 20*03ce13f7SAndroid Build Coastguard Worker #include <errno.h> 21*03ce13f7SAndroid Build Coastguard Worker #include <string.h> 22*03ce13f7SAndroid Build Coastguard Worker #include <sys/mman.h> 23*03ce13f7SAndroid Build Coastguard Worker 24*03ce13f7SAndroid Build Coastguard Worker class OpaqueFdExternalMemory : public vk::DeviceMemory, public vk::ObjectBase<OpaqueFdExternalMemory, VkDeviceMemory> 25*03ce13f7SAndroid Build Coastguard Worker { 26*03ce13f7SAndroid Build Coastguard Worker public: 27*03ce13f7SAndroid Build Coastguard Worker static const VkExternalMemoryHandleTypeFlagBits typeFlagBit = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT; 28*03ce13f7SAndroid Build Coastguard Worker SupportsAllocateInfo(const vk::DeviceMemory::ExtendedAllocationInfo & extendedAllocationInfo)29*03ce13f7SAndroid Build Coastguard Worker static bool SupportsAllocateInfo(const vk::DeviceMemory::ExtendedAllocationInfo &extendedAllocationInfo) 30*03ce13f7SAndroid Build Coastguard Worker { 31*03ce13f7SAndroid Build Coastguard Worker OpaqueFdAllocateInfo info(extendedAllocationInfo); 32*03ce13f7SAndroid Build Coastguard Worker return info.importFd || info.exportFd; 33*03ce13f7SAndroid Build Coastguard Worker } 34*03ce13f7SAndroid Build Coastguard Worker OpaqueFdExternalMemory(const VkMemoryAllocateInfo * pCreateInfo,void * mem,const vk::DeviceMemory::ExtendedAllocationInfo & extendedAllocationInfo,vk::Device * pDevice)35*03ce13f7SAndroid Build Coastguard Worker explicit OpaqueFdExternalMemory(const VkMemoryAllocateInfo *pCreateInfo, void *mem, const vk::DeviceMemory::ExtendedAllocationInfo &extendedAllocationInfo, vk::Device *pDevice) 36*03ce13f7SAndroid Build Coastguard Worker : vk::DeviceMemory(pCreateInfo, extendedAllocationInfo, pDevice) 37*03ce13f7SAndroid Build Coastguard Worker , allocateInfo(extendedAllocationInfo) 38*03ce13f7SAndroid Build Coastguard Worker { 39*03ce13f7SAndroid Build Coastguard Worker } 40*03ce13f7SAndroid Build Coastguard Worker ~OpaqueFdExternalMemory()41*03ce13f7SAndroid Build Coastguard Worker ~OpaqueFdExternalMemory() 42*03ce13f7SAndroid Build Coastguard Worker { 43*03ce13f7SAndroid Build Coastguard Worker memfd.close(); 44*03ce13f7SAndroid Build Coastguard Worker } 45*03ce13f7SAndroid Build Coastguard Worker allocateBuffer()46*03ce13f7SAndroid Build Coastguard Worker VkResult allocateBuffer() override 47*03ce13f7SAndroid Build Coastguard Worker { 48*03ce13f7SAndroid Build Coastguard Worker if(allocateInfo.importFd) 49*03ce13f7SAndroid Build Coastguard Worker { 50*03ce13f7SAndroid Build Coastguard Worker memfd.importFd(allocateInfo.fd); 51*03ce13f7SAndroid Build Coastguard Worker if(!memfd.isValid()) 52*03ce13f7SAndroid Build Coastguard Worker { 53*03ce13f7SAndroid Build Coastguard Worker return VK_ERROR_INVALID_EXTERNAL_HANDLE; 54*03ce13f7SAndroid Build Coastguard Worker } 55*03ce13f7SAndroid Build Coastguard Worker } 56*03ce13f7SAndroid Build Coastguard Worker else 57*03ce13f7SAndroid Build Coastguard Worker { 58*03ce13f7SAndroid Build Coastguard Worker ASSERT(allocateInfo.exportFd); 59*03ce13f7SAndroid Build Coastguard Worker static int counter = 0; 60*03ce13f7SAndroid Build Coastguard Worker char name[40]; 61*03ce13f7SAndroid Build Coastguard Worker snprintf(name, sizeof(name), "SwiftShader.Memory.%d", ++counter); 62*03ce13f7SAndroid Build Coastguard Worker if(!memfd.allocate(name, allocationSize)) 63*03ce13f7SAndroid Build Coastguard Worker { 64*03ce13f7SAndroid Build Coastguard Worker TRACE("memfd.allocate() returned %s", strerror(errno)); 65*03ce13f7SAndroid Build Coastguard Worker return VK_ERROR_OUT_OF_DEVICE_MEMORY; 66*03ce13f7SAndroid Build Coastguard Worker } 67*03ce13f7SAndroid Build Coastguard Worker } 68*03ce13f7SAndroid Build Coastguard Worker void *addr = memfd.mapReadWrite(0, allocationSize); 69*03ce13f7SAndroid Build Coastguard Worker if(!addr) 70*03ce13f7SAndroid Build Coastguard Worker { 71*03ce13f7SAndroid Build Coastguard Worker return VK_ERROR_MEMORY_MAP_FAILED; 72*03ce13f7SAndroid Build Coastguard Worker } 73*03ce13f7SAndroid Build Coastguard Worker buffer = addr; 74*03ce13f7SAndroid Build Coastguard Worker return VK_SUCCESS; 75*03ce13f7SAndroid Build Coastguard Worker } 76*03ce13f7SAndroid Build Coastguard Worker freeBuffer()77*03ce13f7SAndroid Build Coastguard Worker void freeBuffer() override 78*03ce13f7SAndroid Build Coastguard Worker { 79*03ce13f7SAndroid Build Coastguard Worker memfd.unmap(buffer, allocationSize); 80*03ce13f7SAndroid Build Coastguard Worker } 81*03ce13f7SAndroid Build Coastguard Worker getFlagBit() const82*03ce13f7SAndroid Build Coastguard Worker VkExternalMemoryHandleTypeFlagBits getFlagBit() const override 83*03ce13f7SAndroid Build Coastguard Worker { 84*03ce13f7SAndroid Build Coastguard Worker return typeFlagBit; 85*03ce13f7SAndroid Build Coastguard Worker } 86*03ce13f7SAndroid Build Coastguard Worker exportFd(int * pFd) const87*03ce13f7SAndroid Build Coastguard Worker VkResult exportFd(int *pFd) const override 88*03ce13f7SAndroid Build Coastguard Worker { 89*03ce13f7SAndroid Build Coastguard Worker int fd = memfd.exportFd(); 90*03ce13f7SAndroid Build Coastguard Worker if(fd < 0) 91*03ce13f7SAndroid Build Coastguard Worker { 92*03ce13f7SAndroid Build Coastguard Worker return VK_ERROR_INVALID_EXTERNAL_HANDLE; 93*03ce13f7SAndroid Build Coastguard Worker } 94*03ce13f7SAndroid Build Coastguard Worker *pFd = fd; 95*03ce13f7SAndroid Build Coastguard Worker return VK_SUCCESS; 96*03ce13f7SAndroid Build Coastguard Worker } 97*03ce13f7SAndroid Build Coastguard Worker 98*03ce13f7SAndroid Build Coastguard Worker private: 99*03ce13f7SAndroid Build Coastguard Worker LinuxMemFd memfd; 100*03ce13f7SAndroid Build Coastguard Worker OpaqueFdAllocateInfo allocateInfo; 101*03ce13f7SAndroid Build Coastguard Worker }; 102