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 #include "VkStringify.hpp" 17*03ce13f7SAndroid Build Coastguard Worker 18*03ce13f7SAndroid Build Coastguard Worker #include "System/Debug.hpp" 19*03ce13f7SAndroid Build Coastguard Worker 20*03ce13f7SAndroid Build Coastguard Worker #include <zircon/process.h> 21*03ce13f7SAndroid Build Coastguard Worker #include <zircon/syscalls.h> 22*03ce13f7SAndroid Build Coastguard Worker 23*03ce13f7SAndroid Build Coastguard Worker namespace zircon { 24*03ce13f7SAndroid Build Coastguard Worker 25*03ce13f7SAndroid Build Coastguard Worker class VmoExternalMemory : public vk::DeviceMemory, public vk::ObjectBase<VmoExternalMemory, VkDeviceMemory> 26*03ce13f7SAndroid Build Coastguard Worker { 27*03ce13f7SAndroid Build Coastguard Worker public: 28*03ce13f7SAndroid Build Coastguard Worker // Helper struct which reads the parsed allocation info and 29*03ce13f7SAndroid Build Coastguard Worker // extracts relevant information related to the handle type 30*03ce13f7SAndroid Build Coastguard Worker // supported by this DeviceMemory subclass. 31*03ce13f7SAndroid Build Coastguard Worker struct AllocateInfo 32*03ce13f7SAndroid Build Coastguard Worker { 33*03ce13f7SAndroid Build Coastguard Worker bool importHandle = false; 34*03ce13f7SAndroid Build Coastguard Worker bool exportHandle = false; 35*03ce13f7SAndroid Build Coastguard Worker zx_handle_t handle = ZX_HANDLE_INVALID; 36*03ce13f7SAndroid Build Coastguard Worker 37*03ce13f7SAndroid Build Coastguard Worker AllocateInfo() = default; 38*03ce13f7SAndroid Build Coastguard Worker 39*03ce13f7SAndroid Build Coastguard Worker // Use the parsed allocation info to initialize a AllocateInfo. AllocateInfozircon::VmoExternalMemory::AllocateInfo40*03ce13f7SAndroid Build Coastguard Worker AllocateInfo(const vk::DeviceMemory::ExtendedAllocationInfo &extendedAllocationInfo) 41*03ce13f7SAndroid Build Coastguard Worker { 42*03ce13f7SAndroid Build Coastguard Worker if(extendedAllocationInfo.importMemoryZirconHandleInfo) 43*03ce13f7SAndroid Build Coastguard Worker { 44*03ce13f7SAndroid Build Coastguard Worker if(extendedAllocationInfo.importMemoryZirconHandleInfo->handleType != VK_EXTERNAL_MEMORY_HANDLE_TYPE_ZIRCON_VMO_BIT_FUCHSIA) 45*03ce13f7SAndroid Build Coastguard Worker { 46*03ce13f7SAndroid Build Coastguard Worker UNSUPPORTED("extendedAllocationInfo.importMemoryZirconHandleInfo->handleType"); 47*03ce13f7SAndroid Build Coastguard Worker } 48*03ce13f7SAndroid Build Coastguard Worker importHandle = true; 49*03ce13f7SAndroid Build Coastguard Worker handle = extendedAllocationInfo.importMemoryZirconHandleInfo->handle; 50*03ce13f7SAndroid Build Coastguard Worker } 51*03ce13f7SAndroid Build Coastguard Worker 52*03ce13f7SAndroid Build Coastguard Worker if(extendedAllocationInfo.exportMemoryAllocateInfo) 53*03ce13f7SAndroid Build Coastguard Worker { 54*03ce13f7SAndroid Build Coastguard Worker if(extendedAllocationInfo.exportMemoryAllocateInfo->handleTypes != VK_EXTERNAL_MEMORY_HANDLE_TYPE_ZIRCON_VMO_BIT_FUCHSIA) 55*03ce13f7SAndroid Build Coastguard Worker { 56*03ce13f7SAndroid Build Coastguard Worker UNSUPPORTED("extendedAllocationInfo.exportMemoryAllocateInfo->handleTypes"); 57*03ce13f7SAndroid Build Coastguard Worker } 58*03ce13f7SAndroid Build Coastguard Worker exportHandle = true; 59*03ce13f7SAndroid Build Coastguard Worker } 60*03ce13f7SAndroid Build Coastguard Worker } 61*03ce13f7SAndroid Build Coastguard Worker }; 62*03ce13f7SAndroid Build Coastguard Worker 63*03ce13f7SAndroid Build Coastguard Worker static const VkExternalMemoryHandleTypeFlagBits typeFlagBit = VK_EXTERNAL_MEMORY_HANDLE_TYPE_ZIRCON_VMO_BIT_FUCHSIA; 64*03ce13f7SAndroid Build Coastguard Worker supportsAllocateInfo(const vk::DeviceMemory::ExtendedAllocationInfo & extendedAllocationInfo)65*03ce13f7SAndroid Build Coastguard Worker static bool supportsAllocateInfo(const vk::DeviceMemory::ExtendedAllocationInfo &extendedAllocationInfo) 66*03ce13f7SAndroid Build Coastguard Worker { 67*03ce13f7SAndroid Build Coastguard Worker AllocateInfo info(extendedAllocationInfo); 68*03ce13f7SAndroid Build Coastguard Worker return info.importHandle || info.exportHandle; 69*03ce13f7SAndroid Build Coastguard Worker } 70*03ce13f7SAndroid Build Coastguard Worker VmoExternalMemory(const VkMemoryAllocateInfo * pCreateInfo,void * mem,const vk::DeviceMemory::ExtendedAllocationInfo & extendedAllocationInfo,vk::Device * pDevice)71*03ce13f7SAndroid Build Coastguard Worker explicit VmoExternalMemory(const VkMemoryAllocateInfo *pCreateInfo, void *mem, const vk::DeviceMemory::ExtendedAllocationInfo &extendedAllocationInfo, vk::Device *pDevice) 72*03ce13f7SAndroid Build Coastguard Worker : vk::DeviceMemory(pCreateInfo, extendedAllocationInfo, pDevice) 73*03ce13f7SAndroid Build Coastguard Worker , allocateInfo(extendedAllocationInfo) 74*03ce13f7SAndroid Build Coastguard Worker { 75*03ce13f7SAndroid Build Coastguard Worker } 76*03ce13f7SAndroid Build Coastguard Worker ~VmoExternalMemory()77*03ce13f7SAndroid Build Coastguard Worker ~VmoExternalMemory() 78*03ce13f7SAndroid Build Coastguard Worker { 79*03ce13f7SAndroid Build Coastguard Worker closeVmo(); 80*03ce13f7SAndroid Build Coastguard Worker } 81*03ce13f7SAndroid Build Coastguard Worker allocateBuffer()82*03ce13f7SAndroid Build Coastguard Worker VkResult allocateBuffer() override 83*03ce13f7SAndroid Build Coastguard Worker { 84*03ce13f7SAndroid Build Coastguard Worker if(allocateInfo.importHandle) 85*03ce13f7SAndroid Build Coastguard Worker { 86*03ce13f7SAndroid Build Coastguard Worker // NOTE: handle ownership is passed to the VkDeviceMemory. 87*03ce13f7SAndroid Build Coastguard Worker vmoHandle = allocateInfo.handle; 88*03ce13f7SAndroid Build Coastguard Worker } 89*03ce13f7SAndroid Build Coastguard Worker else 90*03ce13f7SAndroid Build Coastguard Worker { 91*03ce13f7SAndroid Build Coastguard Worker ASSERT(allocateInfo.exportHandle); 92*03ce13f7SAndroid Build Coastguard Worker zx_status_t status = zx_vmo_create(allocationSize, 0, &vmoHandle); 93*03ce13f7SAndroid Build Coastguard Worker if(status != ZX_OK) 94*03ce13f7SAndroid Build Coastguard Worker { 95*03ce13f7SAndroid Build Coastguard Worker TRACE("zx_vmo_create() returned %d", status); 96*03ce13f7SAndroid Build Coastguard Worker return VK_ERROR_OUT_OF_DEVICE_MEMORY; 97*03ce13f7SAndroid Build Coastguard Worker } 98*03ce13f7SAndroid Build Coastguard Worker } 99*03ce13f7SAndroid Build Coastguard Worker 100*03ce13f7SAndroid Build Coastguard Worker // Now map it directly. 101*03ce13f7SAndroid Build Coastguard Worker zx_vaddr_t addr = 0; 102*03ce13f7SAndroid Build Coastguard Worker zx_status_t status = zx_vmar_map(zx_vmar_root_self(), 103*03ce13f7SAndroid Build Coastguard Worker ZX_VM_PERM_READ | ZX_VM_PERM_WRITE, 104*03ce13f7SAndroid Build Coastguard Worker 0, // vmar_offset 105*03ce13f7SAndroid Build Coastguard Worker vmoHandle, 106*03ce13f7SAndroid Build Coastguard Worker 0, // vmo_offset 107*03ce13f7SAndroid Build Coastguard Worker allocationSize, 108*03ce13f7SAndroid Build Coastguard Worker &addr); 109*03ce13f7SAndroid Build Coastguard Worker if(status != ZX_OK) 110*03ce13f7SAndroid Build Coastguard Worker { 111*03ce13f7SAndroid Build Coastguard Worker TRACE("zx_vmar_map() failed with %d", status); 112*03ce13f7SAndroid Build Coastguard Worker return VK_ERROR_MEMORY_MAP_FAILED; 113*03ce13f7SAndroid Build Coastguard Worker } 114*03ce13f7SAndroid Build Coastguard Worker buffer = reinterpret_cast<void *>(addr); 115*03ce13f7SAndroid Build Coastguard Worker return VK_SUCCESS; 116*03ce13f7SAndroid Build Coastguard Worker } 117*03ce13f7SAndroid Build Coastguard Worker freeBuffer()118*03ce13f7SAndroid Build Coastguard Worker void freeBuffer() override 119*03ce13f7SAndroid Build Coastguard Worker { 120*03ce13f7SAndroid Build Coastguard Worker zx_status_t status = zx_vmar_unmap(zx_vmar_root_self(), 121*03ce13f7SAndroid Build Coastguard Worker reinterpret_cast<zx_vaddr_t>(buffer), 122*03ce13f7SAndroid Build Coastguard Worker allocationSize); 123*03ce13f7SAndroid Build Coastguard Worker if(status != ZX_OK) 124*03ce13f7SAndroid Build Coastguard Worker { 125*03ce13f7SAndroid Build Coastguard Worker TRACE("zx_vmar_unmap() failed with %d", status); 126*03ce13f7SAndroid Build Coastguard Worker } 127*03ce13f7SAndroid Build Coastguard Worker closeVmo(); 128*03ce13f7SAndroid Build Coastguard Worker } 129*03ce13f7SAndroid Build Coastguard Worker getFlagBit() const130*03ce13f7SAndroid Build Coastguard Worker VkExternalMemoryHandleTypeFlagBits getFlagBit() const override 131*03ce13f7SAndroid Build Coastguard Worker { 132*03ce13f7SAndroid Build Coastguard Worker return typeFlagBit; 133*03ce13f7SAndroid Build Coastguard Worker } 134*03ce13f7SAndroid Build Coastguard Worker exportHandle(zx_handle_t * pHandle) const135*03ce13f7SAndroid Build Coastguard Worker VkResult exportHandle(zx_handle_t *pHandle) const override 136*03ce13f7SAndroid Build Coastguard Worker { 137*03ce13f7SAndroid Build Coastguard Worker if(vmoHandle == ZX_HANDLE_INVALID) 138*03ce13f7SAndroid Build Coastguard Worker { 139*03ce13f7SAndroid Build Coastguard Worker return VK_ERROR_INVALID_EXTERNAL_HANDLE; 140*03ce13f7SAndroid Build Coastguard Worker } 141*03ce13f7SAndroid Build Coastguard Worker zx_status_t status = zx_handle_duplicate(vmoHandle, ZX_RIGHT_SAME_RIGHTS, pHandle); 142*03ce13f7SAndroid Build Coastguard Worker if(status != ZX_OK) 143*03ce13f7SAndroid Build Coastguard Worker { 144*03ce13f7SAndroid Build Coastguard Worker TRACE("zx_handle_duplicate() returned %d", status); 145*03ce13f7SAndroid Build Coastguard Worker return VK_ERROR_INVALID_EXTERNAL_HANDLE; 146*03ce13f7SAndroid Build Coastguard Worker } 147*03ce13f7SAndroid Build Coastguard Worker return VK_SUCCESS; 148*03ce13f7SAndroid Build Coastguard Worker } 149*03ce13f7SAndroid Build Coastguard Worker 150*03ce13f7SAndroid Build Coastguard Worker private: closeVmo()151*03ce13f7SAndroid Build Coastguard Worker void closeVmo() 152*03ce13f7SAndroid Build Coastguard Worker { 153*03ce13f7SAndroid Build Coastguard Worker if(vmoHandle != ZX_HANDLE_INVALID) 154*03ce13f7SAndroid Build Coastguard Worker { 155*03ce13f7SAndroid Build Coastguard Worker zx_handle_close(vmoHandle); 156*03ce13f7SAndroid Build Coastguard Worker vmoHandle = ZX_HANDLE_INVALID; 157*03ce13f7SAndroid Build Coastguard Worker } 158*03ce13f7SAndroid Build Coastguard Worker } 159*03ce13f7SAndroid Build Coastguard Worker 160*03ce13f7SAndroid Build Coastguard Worker zx_handle_t vmoHandle = ZX_HANDLE_INVALID; 161*03ce13f7SAndroid Build Coastguard Worker AllocateInfo allocateInfo; 162*03ce13f7SAndroid Build Coastguard Worker }; 163*03ce13f7SAndroid Build Coastguard Worker 164*03ce13f7SAndroid Build Coastguard Worker } // namespace zircon 165