Merge "Hint buffer creations for VulkanAllocateHostMemory" into main
diff --git a/common/end2end/GfxstreamEnd2EndVkSnapshotPipelineTests.cpp b/common/end2end/GfxstreamEnd2EndVkSnapshotPipelineTests.cpp
index f7a612c..7bd14a9 100644
--- a/common/end2end/GfxstreamEnd2EndVkSnapshotPipelineTests.cpp
+++ b/common/end2end/GfxstreamEnd2EndVkSnapshotPipelineTests.cpp
@@ -526,6 +526,7 @@
commandBuffer->reset();
SnapshotSaveAndLoad();
+ ASSERT_THAT(device->getFenceStatus(*fence), IsVkSuccess());
// TODO(b/332763326): fix validation layer complain about unreleased pipeline layout
// Try to draw something.
diff --git a/guest/platform/kumquat/VirtGpuKumquat.h b/guest/platform/kumquat/VirtGpuKumquat.h
index d940ffd..d22f210 100644
--- a/guest/platform/kumquat/VirtGpuKumquat.h
+++ b/guest/platform/kumquat/VirtGpuKumquat.h
@@ -17,7 +17,13 @@
#pragma once
#include "VirtGpu.h"
+
+// Blueprint and Meson builds place things differently
+#if defined(ANDROID)
+#include "virtgpu_kumquat_ffi.h"
+#else
#include "virtgpu_kumquat/virtgpu_kumquat_ffi.h"
+#endif
class VirtGpuKumquatResource : public std::enable_shared_from_this<VirtGpuKumquatResource>,
public VirtGpuResource {
diff --git a/guest/platform/kumquat/VirtGpuKumquatBlob.cpp b/guest/platform/kumquat/VirtGpuKumquatBlob.cpp
index cd0e3e0..991d53d 100644
--- a/guest/platform/kumquat/VirtGpuKumquatBlob.cpp
+++ b/guest/platform/kumquat/VirtGpuKumquatBlob.cpp
@@ -23,7 +23,6 @@
#include <cstring>
#include "VirtGpuKumquat.h"
-#include "virtgpu_kumquat/virtgpu_kumquat_ffi.h"
VirtGpuKumquatResource::VirtGpuKumquatResource(struct virtgpu_kumquat* virtGpu, uint32_t blobHandle,
uint32_t resourceHandle, uint64_t size)
@@ -53,7 +52,8 @@
ret = virtgpu_kumquat_resource_map(mVirtGpu, &map);
if (ret < 0) {
- ALOGE("Mapping failed with %s", strerror(errno));
+ ALOGE("Mapping failed with %s for resource %u blob %u", strerror(errno), mResourceHandle,
+ mBlobHandle);
return nullptr;
}
diff --git a/guest/platform/kumquat/VirtGpuKumquatDevice.cpp b/guest/platform/kumquat/VirtGpuKumquatDevice.cpp
index 6101cc1..774c9dc 100644
--- a/guest/platform/kumquat/VirtGpuKumquatDevice.cpp
+++ b/guest/platform/kumquat/VirtGpuKumquatDevice.cpp
@@ -26,15 +26,13 @@
#include "VirtGpuKumquat.h"
#include "virtgpu_gfxstream_protocol.h"
-#include "virtgpu_kumquat/virtgpu_kumquat_ffi.h"
#define PARAM(x) \
(struct VirtGpuParam) { x, #x, 0 }
static inline uint32_t align_up(uint32_t n, uint32_t a) { return ((n + a - 1) / a) * a; }
-VirtGpuKumquatDevice::VirtGpuKumquatDevice(enum VirtGpuCapset capset, int fd)
- : VirtGpuDevice(capset) {
+VirtGpuKumquatDevice::VirtGpuKumquatDevice(enum VirtGpuCapset capset, int) : VirtGpuDevice(capset) {
struct VirtGpuParam params[] = {
PARAM(VIRTGPU_KUMQUAT_PARAM_3D_FEATURES),
PARAM(VIRTGPU_KUMQUAT_PARAM_CAPSET_QUERY_FIX),
@@ -60,7 +58,7 @@
processName = getprogname();
#endif
- ret = virtgpu_kumquat_init(&mVirtGpu);
+ ret = virtgpu_kumquat_init(&mVirtGpu, nullptr);
if (ret) {
ALOGV("Failed to init virtgpu kumquat");
return;
diff --git a/guest/platform/kumquat/VirtGpuKumquatSync.cpp b/guest/platform/kumquat/VirtGpuKumquatSync.cpp
index d152bff..47884fc 100644
--- a/guest/platform/kumquat/VirtGpuKumquatSync.cpp
+++ b/guest/platform/kumquat/VirtGpuKumquatSync.cpp
@@ -23,9 +23,24 @@
VirtGpuKumquatSyncHelper::VirtGpuKumquatSyncHelper() {}
int VirtGpuKumquatSyncHelper::wait(int syncFd, int timeoutMilliseconds) {
- (void)syncFd;
(void)timeoutMilliseconds;
- return -1;
+ // So far, syncfds are EventFd in the Kumquat layer. This may change
+ uint64_t count = 1;
+ ssize_t bytes_read = read(syncFd, &count, sizeof(count));
+
+ if (bytes_read < 0) {
+ return bytes_read;
+ }
+
+ // A successful read decrements the eventfd's counter to zero. In
+ // case the eventfd is waited on again, or a dup is waited on, we
+ // have to write to the eventfd for the next read.
+ ssize_t bytes_written = write(syncFd, &count, sizeof(count));
+ if (bytes_written < 0) {
+ return bytes_written;
+ }
+
+ return 0;
}
int VirtGpuKumquatSyncHelper::dup(int syncFd) { return ::dup(syncFd); }
diff --git a/host/vulkan/VkCommonOperations.cpp b/host/vulkan/VkCommonOperations.cpp
index 21b1ff7..529dd1b 100644
--- a/host/vulkan/VkCommonOperations.cpp
+++ b/host/vulkan/VkCommonOperations.cpp
@@ -826,16 +826,20 @@
deviceInfos[i].supportsDriverProperties =
extensionsSupported(deviceExts, {VK_KHR_DRIVER_PROPERTIES_EXTENSION_NAME}) ||
(deviceInfos[i].physdevProps.apiVersion >= VK_API_VERSION_1_2);
+ deviceInfos[i].supportsExternalMemoryHostProps = extensionsSupported(deviceExts, {VK_EXT_EXTERNAL_MEMORY_HOST_EXTENSION_NAME});
if (!sVkEmulation->getPhysicalDeviceProperties2Func) {
ERR("Warning: device claims to support ID properties "
"but vkGetPhysicalDeviceProperties2 could not be found");
}
}
-
if (sVkEmulation->getPhysicalDeviceProperties2Func) {
+ VkPhysicalDeviceExternalMemoryHostPropertiesEXT externalMemoryHostProps = {
+ .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_HOST_PROPERTIES_EXT,
+ };
VkPhysicalDeviceProperties2 deviceProps = {
- VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR,
+ .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR,
+
};
VkPhysicalDeviceIDProperties idProps = {
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES_KHR,
@@ -854,9 +858,12 @@
vk_append_struct(&devicePropsChain, &driverProps);
}
+ if(deviceInfos[i].supportsExternalMemoryHostProps) {
+ vk_append_struct(&devicePropsChain, &externalMemoryHostProps);
+ }
sVkEmulation->getPhysicalDeviceProperties2Func(physdevs[i], &deviceProps);
-
deviceInfos[i].idProps = vk_make_orphan_copy(idProps);
+ deviceInfos[i].externalMemoryHostProps = vk_make_orphan_copy(externalMemoryHostProps);
std::stringstream driverVendorBuilder;
driverVendorBuilder << "Vendor " << std::hex << std::setfill('0') << std::showbase
@@ -990,7 +997,6 @@
// in use cases that make sense, if/when they come up.
std::vector<uint32_t> deviceScores(physdevCount, 0);
-
for (uint32_t i = 0; i < physdevCount; ++i) {
uint32_t deviceScore = 0;
if (deviceInfos[i].hasGraphicsQueueFamily) deviceScore += 10000;
diff --git a/host/vulkan/VkCommonOperations.h b/host/vulkan/VkCommonOperations.h
index 43ebc91..a896a2a 100644
--- a/host/vulkan/VkCommonOperations.h
+++ b/host/vulkan/VkCommonOperations.h
@@ -206,6 +206,7 @@
bool supportsDmaBuf = false;
bool supportsIdProperties = false;
bool supportsDriverProperties = false;
+ bool supportsExternalMemoryHostProps = false;
bool hasSamplerYcbcrConversionExtension = false;
bool supportsSamplerYcbcrConversion = false;
bool glInteropSupported = false;
@@ -220,6 +221,7 @@
VkPhysicalDeviceProperties physdevProps;
VkPhysicalDeviceMemoryProperties memProps;
VkPhysicalDeviceIDPropertiesKHR idProps;
+ VkPhysicalDeviceExternalMemoryHostPropertiesEXT externalMemoryHostProps;
std::string driverVendor;
std::string driverVersion;
diff --git a/host/vulkan/VkDecoderGlobalState.cpp b/host/vulkan/VkDecoderGlobalState.cpp
index 2d2ea2b..013acb4 100644
--- a/host/vulkan/VkDecoderGlobalState.cpp
+++ b/host/vulkan/VkDecoderGlobalState.cpp
@@ -194,6 +194,7 @@
static uint32_t kTemporaryContextIdForSnapshotLoading = 1;
static std::unordered_set<std::string> kSnapshotAppAllowList = {"Chromium"};
+static std::unordered_set<std::string> kSnapshotEngineAllowList = {"ANGLE"};
#define DEFINE_BOXED_HANDLE_TYPE_TAG(type) Tag_##type,
@@ -676,6 +677,22 @@
}
}
}
+
+ // Fences
+ std::vector<VkFence> unsignaledFencesBoxed;
+ for (const auto& fence : mFenceInfo) {
+ if (!fence.second.boxed) {
+ continue;
+ }
+ const auto& device = fence.second.device;
+ const auto& deviceInfo = android::base::find(mDeviceInfo, device);
+ VulkanDispatch* dvk = dispatch_VkDevice(deviceInfo->boxed);
+ if (VK_NOT_READY == dvk->vkGetFenceStatus(device, fence.first)) {
+ unsignaledFencesBoxed.push_back(fence.second.boxed);
+ }
+ }
+ stream->putBe64(unsignaledFencesBoxed.size());
+ stream->write(unsignaledFencesBoxed.data(), unsignaledFencesBoxed.size() * sizeof(VkFence));
mSnapshotState = SnapshotState::Normal;
}
@@ -857,7 +874,22 @@
poolIds.data(), whichPool.data(), pendingAlloc.data(), writeStartingIndices.data(),
writeDescriptorSets.size(), writeDescriptorSets.data());
}
-
+ // Fences
+ uint64_t fenceCount = stream->getBe64();
+ std::vector<VkFence> unsignaledFencesBoxed(fenceCount);
+ stream->read(unsignaledFencesBoxed.data(), fenceCount * sizeof(VkFence));
+ for (VkFence boxedFence : unsignaledFencesBoxed) {
+ VkFence unboxedFence = unbox_VkFence(boxedFence);
+ auto it = mFenceInfo.find(unboxedFence);
+ if (it == mFenceInfo.end()) {
+ GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
+ << "Snapshot load failure: unrecognized VkFence";
+ }
+ const auto& device = it->second.device;
+ const auto& deviceInfo = android::base::find(mDeviceInfo, device);
+ VulkanDispatch* dvk = dispatch_VkDevice(deviceInfo->boxed);
+ dvk->vkResetFences(device, 1, &unboxedFence);
+ }
#ifdef GFXSTREAM_ENABLE_HOST_VK_SNAPSHOT
if (!mInstanceInfo.empty()) {
get_emugl_vm_operations().setStatSnapshotUseVulkan();
@@ -1009,9 +1041,9 @@
#ifdef GFXSTREAM_ENABLE_HOST_VK_SNAPSHOT
// TODO: bug 129484301
- if (!m_emu->features.VulkanSnapshots.enabled
- || kSnapshotAppAllowList.find(info.applicationName)
- == kSnapshotAppAllowList.end()) {
+ if (!m_emu->features.VulkanSnapshots.enabled ||
+ (kSnapshotAppAllowList.find(info.applicationName) == kSnapshotAppAllowList.end() &&
+ kSnapshotEngineAllowList.find(info.engineName) == kSnapshotEngineAllowList.end())) {
get_emugl_vm_operations().setSkipSnapshotSave(true);
get_emugl_vm_operations().setSkipSnapshotSaveReason(SNAPSHOT_SKIP_UNSUPPORTED_VK_APP);
}
@@ -2696,6 +2728,13 @@
VkResult on_vkCreateFence(android::base::BumpPool* pool, VkDevice boxed_device,
const VkFenceCreateInfo* pCreateInfo,
const VkAllocationCallbacks* pAllocator, VkFence* pFence) {
+ VkFenceCreateInfo localCreateInfo;
+ if (mSnapshotState == SnapshotState::Loading) {
+ // On snapshot load we create all fences as signaled then reset those that are not.
+ localCreateInfo = *pCreateInfo;
+ pCreateInfo = &localCreateInfo;
+ localCreateInfo.flags |= VK_FENCE_CREATE_SIGNALED_BIT;
+ }
auto device = unbox_VkDevice(boxed_device);
auto vk = dispatch_VkDevice(boxed_device);
@@ -4820,10 +4859,16 @@
VkImportMemoryHostPointerInfoEXT importHostInfoPrivate{};
if (hostVisible && m_emu->features.VulkanAllocateHostMemory.enabled &&
localAllocInfo.pNext == nullptr) {
- VkDeviceSize alignedSize = __ALIGN(localAllocInfo.allocationSize, kPageSizeforBlob);
+ if (!m_emu || !m_emu->deviceInfo.supportsExternalMemoryHostProps) {
+ ERR("VK_EXT_EXTERNAL_MEMORY_HOST is not supported, cannot use "
+ "VulkanAllocateHostMemory");
+ return VK_ERROR_INCOMPATIBLE_DRIVER;
+ }
+ VkDeviceSize alignmentSize = m_emu->deviceInfo.externalMemoryHostProps.minImportedHostPointerAlignment;
+ VkDeviceSize alignedSize = __ALIGN(localAllocInfo.allocationSize, alignmentSize);
localAllocInfo.allocationSize = alignedSize;
privateMemory =
- std::make_shared<PrivateMemory>(kPageSizeforBlob, localAllocInfo.allocationSize);
+ std::make_shared<PrivateMemory>(alignmentSize, localAllocInfo.allocationSize);
mappedPtr = privateMemory->getAddr();
importHostInfoPrivate = {
.sType = VK_STRUCTURE_TYPE_IMPORT_MEMORY_HOST_POINTER_INFO_EXT,
@@ -4831,25 +4876,28 @@
.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT,
.pHostPointer = mappedPtr};
- VkMemoryHostPointerPropertiesEXT pMemoryHostPointerProperties = {
+ VkMemoryHostPointerPropertiesEXT memoryHostPointerProperties = {
.sType = VK_STRUCTURE_TYPE_MEMORY_HOST_POINTER_PROPERTIES_EXT,
.pNext = NULL,
.memoryTypeBits = 0,
};
- vk->vkGetMemoryHostPointerPropertiesEXT(device, VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT, mappedPtr, &pMemoryHostPointerProperties);
- if (pMemoryHostPointerProperties.memoryTypeBits == 0) {
- // Memory import operation not supported by the driver.
+ vk->vkGetMemoryHostPointerPropertiesEXT(
+ device, VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT, mappedPtr,
+ &memoryHostPointerProperties);
+
+ if (memoryHostPointerProperties.memoryTypeBits == 0) {
+ ERR("Cannot find suitable memory type for VulkanAllocateHostMemory");
return VK_ERROR_INCOMPATIBLE_DRIVER;
}
- if (((1u << localAllocInfo.memoryTypeIndex) & pMemoryHostPointerProperties.memoryTypeBits) == 0) {
+ if (((1u << localAllocInfo.memoryTypeIndex) & memoryHostPointerProperties.memoryTypeBits) == 0) {
// TODO Consider assigning the correct memory index earlier, instead of switching right before allocation.
// Look for the first available supported memory index and assign it.
for(uint32_t i =0; i<= 31; ++i) {
- if ((pMemoryHostPointerProperties.memoryTypeBits & (1u << i)) == 0) {
+ if ((memoryHostPointerProperties.memoryTypeBits & (1u << i)) == 0) {
continue;
}
localAllocInfo.memoryTypeIndex = i;
diff --git a/host/vulkan/cereal/common/vk_struct_id.h b/host/vulkan/cereal/common/vk_struct_id.h
index c526dc1..54641fc 100644
--- a/host/vulkan/cereal/common/vk_struct_id.h
+++ b/host/vulkan/cereal/common/vk_struct_id.h
@@ -99,6 +99,8 @@
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SWAPCHAIN_MAINTENANCE_1_FEATURES_EXT)
REGISTER_VK_STRUCT_ID(VkPhysicalDeviceProtectedMemoryFeatures,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES);
+REGISTER_VK_STRUCT_ID(VkPhysicalDeviceExternalMemoryHostPropertiesEXT,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_HOST_PROPERTIES_EXT);
#if defined(VK_USE_PLATFORM_SCREEN_QNX)
REGISTER_VK_STRUCT_ID(VkPhysicalDeviceExternalMemoryScreenBufferFeaturesQNX,