[vulkan] Alloc host visible memory in blocks
bug: 111137294
might be better than chomping down on 512 mb every time
+ Make host-side build of goldfish_address_space allocate actual
physical addresses
+ Remove spammy print
Change-Id: I9c3c400a88fcd058d0c7547d5c583e4e473e8ca9
diff --git a/system/vulkan_enc/ResourceTracker.cpp b/system/vulkan_enc/ResourceTracker.cpp
index 3fecd09..4f928c2 100644
--- a/system/vulkan_enc/ResourceTracker.cpp
+++ b/system/vulkan_enc/ResourceTracker.cpp
@@ -1,4 +1,4 @@
-/// Copyright (C) 2018 The Android Open Source Project
+// Copyright (C) 2018 The Android Open Source Project
// Copyright (C) 2018 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
@@ -230,11 +230,16 @@
std::vector<VkPhysicalDevice> physicalDevices;
};
+ using HostMemBlocks = std::vector<HostMemAlloc>;
+ using HostMemBlockIndex = size_t;
+
+#define INVALID_HOST_MEM_BLOCK (-1)
+
struct VkDevice_Info {
VkPhysicalDevice physdev;
VkPhysicalDeviceProperties props;
VkPhysicalDeviceMemoryProperties memProps;
- HostMemAlloc hostMemAllocs[VK_MAX_MEMORY_TYPES] = {};
+ std::vector<HostMemBlocks> hostMemBlocks { VK_MAX_MEMORY_TYPES };
uint32_t apiVersion;
std::set<std::string> enabledExtensions;
VkFence fence = VK_NULL_HANDLE;
@@ -1037,7 +1042,9 @@
VkEncoder* enc = (VkEncoder*)context;
for (uint32_t i = 0; i < VK_MAX_MEMORY_TYPES; ++i) {
- destroyHostMemAlloc(enc, device, &info.hostMemAllocs[i]);
+ for (auto& block : info.hostMemBlocks[i]) {
+ destroyHostMemAlloc(enc, device, &block);
+ }
}
if (info.fence != VK_NULL_HANDLE) {
@@ -1286,6 +1293,121 @@
}
#endif
+ HostMemBlockIndex getOrAllocateHostMemBlockLocked(
+ HostMemBlocks& blocks,
+ const VkMemoryAllocateInfo* pAllocateInfo,
+ VkEncoder* enc,
+ VkDevice device,
+ const VkDevice_Info& deviceInfo) {
+
+ HostMemBlockIndex res = 0;
+ bool found = false;
+
+ while (!found) {
+ for (HostMemBlockIndex i = 0; i < blocks.size(); ++i) {
+ if (blocks[i].initialized &&
+ blocks[i].initResult == VK_SUCCESS &&
+ canSubAlloc(
+ blocks[i].subAlloc,
+ pAllocateInfo->allocationSize)) {
+ res = i;
+ found = true;
+ return res;
+ }
+ }
+
+ blocks.push_back({});
+
+ auto& hostMemAlloc = blocks.back();
+
+ // Uninitialized block; allocate on host.
+ static constexpr VkDeviceSize oneMb = 1048576;
+ static constexpr VkDeviceSize kDefaultHostMemBlockSize =
+ 16 * oneMb; // 16 mb
+ VkDeviceSize roundedUpAllocSize =
+ oneMb * ((pAllocateInfo->allocationSize + oneMb - 1) / oneMb);
+
+ VkDeviceSize virtualHeapSize = VIRTUAL_HOST_VISIBLE_HEAP_SIZE;
+
+ VkDeviceSize blockSizeNeeded =
+ std::max(roundedUpAllocSize,
+ std::min(virtualHeapSize,
+ kDefaultHostMemBlockSize));
+
+ VkMemoryAllocateInfo allocInfoForHost = *pAllocateInfo;
+
+ allocInfoForHost.allocationSize = blockSizeNeeded;
+
+ // TODO: Support dedicated/external host visible allocation
+ allocInfoForHost.pNext = nullptr;
+
+ mLock.unlock();
+ VkResult host_res =
+ enc->vkAllocateMemory(
+ device,
+ &allocInfoForHost,
+ nullptr,
+ &hostMemAlloc.memory);
+ mLock.lock();
+
+ if (host_res != VK_SUCCESS) {
+ ALOGE("Could not allocate backing for virtual host visible memory: %d",
+ host_res);
+ hostMemAlloc.initialized = true;
+ hostMemAlloc.initResult = host_res;
+ return INVALID_HOST_MEM_BLOCK;
+ }
+
+ auto& hostMemInfo = info_VkDeviceMemory[hostMemAlloc.memory];
+ hostMemInfo.allocationSize = allocInfoForHost.allocationSize;
+ VkDeviceSize nonCoherentAtomSize =
+ deviceInfo.props.limits.nonCoherentAtomSize;
+ hostMemInfo.mappedSize = hostMemInfo.allocationSize;
+ hostMemInfo.memoryTypeIndex =
+ pAllocateInfo->memoryTypeIndex;
+ hostMemAlloc.nonCoherentAtomSize = nonCoherentAtomSize;
+
+ uint64_t directMappedAddr = 0;
+
+ mLock.unlock();
+ VkResult directMapResult =
+ enc->vkMapMemoryIntoAddressSpaceGOOGLE(
+ device, hostMemAlloc.memory, &directMappedAddr);
+ mLock.lock();
+
+ if (directMapResult != VK_SUCCESS) {
+ hostMemAlloc.initialized = true;
+ hostMemAlloc.initResult = directMapResult;
+ mLock.unlock();
+ enc->vkFreeMemory(device, hostMemAlloc.memory, nullptr);
+ mLock.lock();
+ return INVALID_HOST_MEM_BLOCK;
+ }
+
+ hostMemInfo.mappedPtr =
+ (uint8_t*)(uintptr_t)directMappedAddr;
+ hostMemInfo.virtualHostVisibleBacking = true;
+
+ VkResult hostMemAllocRes =
+ finishHostMemAllocInit(
+ enc,
+ device,
+ pAllocateInfo->memoryTypeIndex,
+ nonCoherentAtomSize,
+ hostMemInfo.allocationSize,
+ hostMemInfo.mappedSize,
+ hostMemInfo.mappedPtr,
+ &hostMemAlloc);
+
+ if (hostMemAllocRes != VK_SUCCESS) {
+ return INVALID_HOST_MEM_BLOCK;
+ }
+ }
+
+ // unreacheable, but we need to make Werror happy
+ return INVALID_HOST_MEM_BLOCK;
+ }
+
VkResult on_vkAllocateMemory(
void* context,
VkResult input_result,
@@ -1458,7 +1580,7 @@
}
if (ahw) {
- ALOGD("%s: AHBIMPORT", __func__);
+ ALOGD("%s: Import AHardwareBulffer", __func__);
const native_handle_t *handle =
AHardwareBuffer_getNativeHandle(ahw);
const cb_handle_t* cb_handle =
@@ -1565,78 +1687,25 @@
if (it == info_VkDevice.end()) return VK_ERROR_DEVICE_LOST;
auto& deviceInfo = it->second;
- HostMemAlloc* hostMemAlloc =
- &deviceInfo.hostMemAllocs[finalAllocInfo.memoryTypeIndex];
+ auto& hostMemBlocksForTypeIndex =
+ deviceInfo.hostMemBlocks[finalAllocInfo.memoryTypeIndex];
- if (!hostMemAlloc->initialized) {
- VkMemoryAllocateInfo allocInfoForHost = finalAllocInfo;
- allocInfoForHost.allocationSize = VIRTUAL_HOST_VISIBLE_HEAP_SIZE;
- // TODO: Support dedicated allocation
- allocInfoForHost.pNext = nullptr;
+ HostMemBlockIndex blockIndex =
+ getOrAllocateHostMemBlockLocked(
+ hostMemBlocksForTypeIndex,
+ &finalAllocInfo,
+ enc,
+ device,
+ deviceInfo);
- lock.unlock();
- VkResult host_res =
- enc->vkAllocateMemory(
- device,
- &allocInfoForHost,
- nullptr,
- &hostMemAlloc->memory);
- lock.lock();
-
- if (host_res != VK_SUCCESS) {
- ALOGE("Could not allocate backing for virtual host visible memory: %d",
- host_res);
- hostMemAlloc->initialized = true;
- hostMemAlloc->initResult = host_res;
- return host_res;
- }
-
- auto& hostMemInfo = info_VkDeviceMemory[hostMemAlloc->memory];
- hostMemInfo.allocationSize = allocInfoForHost.allocationSize;
- VkDeviceSize nonCoherentAtomSize =
- deviceInfo.props.limits.nonCoherentAtomSize;
- hostMemInfo.mappedSize = hostMemInfo.allocationSize;
- hostMemInfo.memoryTypeIndex =
- finalAllocInfo.memoryTypeIndex;
- hostMemAlloc->nonCoherentAtomSize = nonCoherentAtomSize;
-
- uint64_t directMappedAddr = 0;
- lock.unlock();
- VkResult directMapResult =
- enc->vkMapMemoryIntoAddressSpaceGOOGLE(
- device, hostMemAlloc->memory, &directMappedAddr);
- lock.lock();
-
- if (directMapResult != VK_SUCCESS) {
- hostMemAlloc->initialized = true;
- hostMemAlloc->initResult = directMapResult;
- return directMapResult;
- }
-
- hostMemInfo.mappedPtr =
- (uint8_t*)(uintptr_t)directMappedAddr;
- hostMemInfo.virtualHostVisibleBacking = true;
-
- VkResult hostMemAllocRes =
- finishHostMemAllocInit(
- enc,
- device,
- finalAllocInfo.memoryTypeIndex,
- nonCoherentAtomSize,
- hostMemInfo.allocationSize,
- hostMemInfo.mappedSize,
- hostMemInfo.mappedPtr,
- hostMemAlloc);
-
- if (hostMemAllocRes != VK_SUCCESS) {
- return hostMemAllocRes;
- }
+ if (blockIndex == INVALID_HOST_MEM_BLOCK) {
+ return VK_ERROR_OUT_OF_HOST_MEMORY;
}
VkDeviceMemory_Info virtualMemInfo;
subAllocHostMemory(
- hostMemAlloc,
+ &hostMemBlocksForTypeIndex[blockIndex],
&finalAllocInfo,
&virtualMemInfo.subAlloc);