[vulkan] experimental fuchsia platform support
bug: 111137294
- Add goldfish address space on Fuchsia
- Support Fuchsia external memory export via color buffer import
- In Fuchsia, create Android native buffers + colorBuffer on host
for images with color attachment or scanout usage.
- Allow the presence of preSignalSemaphores in vkQueueSubmit.
Change-Id: I0af09953be6095886013c15dbd2e266bb8621abf
diff --git a/BUILD.gn b/BUILD.gn
index 117d514..04c3967 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -73,7 +73,7 @@
"LOG_TAG=\"goldfish_vulkan\"",
"GOLDFISH_VULKAN",
"GOLDFISH_NO_GL",
- "VK_USE_PLATFORM_ANDROID_KHR",
+ "VK_USE_PLATFORM_FUCHSIA",
"PLATFORM_SDK_VERSION=1",
"PAGE_SIZE=4096",
]
@@ -81,6 +81,7 @@
cflags_cc = [
"-Wno-unused-function",
"-Wno-unused-variable",
+ "-Wno-missing-field-initializers",
]
if (target_os == "fuchsia") {
@@ -91,8 +92,20 @@
"fuchsia/include",
]
+ libs = [
+ "zircon"
+ ]
+
+ deps = [
+ "//zircon/public/fidl/fuchsia-hardware-goldfish:fuchsia-hardware-goldfish_c",
+ "//zircon/public/lib/fdio",
+ "//zircon/public/lib/fzl",
+ "//zircon/public/lib/trace",
+ ]
+
defines += [
"QEMU_PIPE_PATH=\"/dev/sys/platform/acpi/goldfish/goldfish-pipe\"",
+ "GOLDFISH_ADDRESS_SPACE_DEVICE_NAME=\"/dev/sys/platform/acpi/goldfish/goldfish-pipe\"",
]
}
}
diff --git a/android-emu/android/base/Tracing.cpp b/android-emu/android/base/Tracing.cpp
index 652e13c..8b254d2 100644
--- a/android-emu/android/base/Tracing.cpp
+++ b/android-emu/android/base/Tracing.cpp
@@ -27,7 +27,7 @@
atrace_begin(VK_TRACE_TAG, name);
}
-void ScopedTrace::endTraceImpl() {
+void ScopedTrace::endTraceImpl(const char*) {
atrace_end(VK_TRACE_TAG);
}
@@ -36,12 +36,20 @@
#elif __Fuchsia__
+#include <trace/event.h>
+
+#define VK_TRACE_TAG "gfx"
+
namespace android {
namespace base {
-// TODO
-void ScopedTrace::beginTraceImpl(const char*) { }
-void ScopedTrace::endTraceImpl()
+void ScopedTrace::beginTraceImpl(const char* name) {
+ TRACE_DURATION_BEGIN(VK_TRACE_TAG, name);
+}
+
+void ScopedTrace::endTraceImpl(const char* name) {
+ TRACE_DURATION_END(VK_TRACE_TAG, name);
+}
} // namespace base
} // namespace android
diff --git a/android-emu/android/base/Tracing.h b/android-emu/android/base/Tracing.h
index 9044b72..046a5bf 100644
--- a/android-emu/android/base/Tracing.h
+++ b/android-emu/android/base/Tracing.h
@@ -21,16 +21,18 @@
class ScopedTrace {
public:
- ScopedTrace(const char* name) {
- beginTraceImpl(name);
+ ScopedTrace(const char* name) : name_(name) {
+ beginTraceImpl(name_);
}
~ScopedTrace() {
- endTraceImpl();
+ endTraceImpl(name_);
}
private:
void beginTraceImpl(const char* name);
- void endTraceImpl();
+ void endTraceImpl(const char* name);
+
+ const char* const name_;
};
} // namespace base
@@ -40,4 +42,4 @@
#define __AEMU_GENSYM1(x,y) __AEMU_GENSYM2(x,y)
#define AEMU_GENSYM(x) __AEMU_GENSYM1(x,__COUNTER__)
-#define AEMU_SCOPED_TRACE(tag) __attribute__ ((unused)) android::base::ScopedTrace AEMU_GENSYM(aemuScopedTrace_)(tag)
\ No newline at end of file
+#define AEMU_SCOPED_TRACE(tag) __attribute__ ((unused)) android::base::ScopedTrace AEMU_GENSYM(aemuScopedTrace_)(tag)
diff --git a/shared/OpenglCodecCommon/goldfish_address_space.cpp b/shared/OpenglCodecCommon/goldfish_address_space.cpp
index 5b23ca5..46420bf 100644
--- a/shared/OpenglCodecCommon/goldfish_address_space.cpp
+++ b/shared/OpenglCodecCommon/goldfish_address_space.cpp
@@ -45,14 +45,189 @@
this->m_guest_ptr = NULL;
}
}
+#elif __Fuchsia__
+#include <fcntl.h>
+#include <fuchsia/hardware/goldfish/c/fidl.h>
+#include <lib/fzl/fdio.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <zircon/process.h>
+#include <zircon/syscalls.h>
+#include <zircon/syscalls/object.h>
+
+GoldfishAddressSpaceBlockProvider::GoldfishAddressSpaceBlockProvider()
+ : m_fd(::open(GOLDFISH_ADDRESS_SPACE_DEVICE_NAME, O_RDWR)) {}
+
+GoldfishAddressSpaceBlockProvider::~GoldfishAddressSpaceBlockProvider()
+{
+ ::close(m_fd);
+}
+
+GoldfishAddressSpaceBlock::GoldfishAddressSpaceBlock()
+ : m_vmo(ZX_HANDLE_INVALID)
+ , m_mmaped_ptr(NULL)
+ , m_phys_addr(0)
+ , m_host_addr(0)
+ , m_offset(0)
+ , m_size(0)
+ , m_fd(-1) {}
+
+GoldfishAddressSpaceBlock::~GoldfishAddressSpaceBlock()
+{
+ destroy();
+}
+
+GoldfishAddressSpaceBlock &GoldfishAddressSpaceBlock::operator=(const GoldfishAddressSpaceBlock &rhs)
+{
+ m_vmo = rhs.m_vmo;
+ m_mmaped_ptr = rhs.m_mmaped_ptr;
+ m_phys_addr = rhs.m_phys_addr;
+ m_host_addr = rhs.m_host_addr;
+ m_offset = rhs.m_offset;
+ m_size = rhs.m_size;
+ m_fd = rhs.m_fd;
+
+ return *this;
+}
+
+bool GoldfishAddressSpaceBlock::allocate(GoldfishAddressSpaceBlockProvider *provider, size_t size)
+{
+ ALOGD("%s: Ask for block of size 0x%llx\n", __func__,
+ (unsigned long long)size);
+
+ destroy();
+
+ if (!provider->is_opened()) {
+ return false;
+ }
+
+ {
+ fzl::FdioCaller caller{fbl::unique_fd(provider->m_fd)};
+
+ int32_t res = ZX_OK;
+ zx_status_t status =
+ fuchsia_hardware_goldfish_DeviceAllocateVmo(caller.borrow_channel(),
+ size, &res, &m_vmo);
+ if (status != ZX_OK || res != ZX_OK) {
+ ALOGE("%s: allocate vmo failed: %d:%d", __func__, status, res);
+ provider->m_fd = caller.release().release();
+ return false;
+ }
+
+ zx_handle_t vmo_out;
+ status = zx_handle_duplicate(m_vmo, ZX_DEFAULT_VMO_RIGHTS, &vmo_out);
+ if (status != ZX_OK) {
+ ALOGE("%s: vmo dup failed: %d:%d", __func__, status);
+ provider->m_fd = caller.release().release();
+ return false;
+ }
+
+ status = fuchsia_hardware_goldfish_DeviceGetPhysicalAddress(
+ caller.borrow_channel(),
+ vmo_out, &res, &m_phys_addr);
+ provider->m_fd = caller.release().release();
+
+ if (status != ZX_OK || res != ZX_OK) {
+ ALOGE("%s: pin vmo failed: %d:%d", __func__, status, res);
+ return false;
+ }
+ }
+
+ m_offset = 0;
+ m_size = size;
+
+ ALOGD("%s: allocate returned offset 0x%llx size 0x%llx\n", __func__,
+ (unsigned long long)m_offset,
+ (unsigned long long)m_size);
+
+ m_fd = provider->m_fd;
+ return true;
+}
+
+uint64_t GoldfishAddressSpaceBlock::physAddr() const
+{
+ return m_phys_addr;
+}
+
+uint64_t GoldfishAddressSpaceBlock::hostAddr() const
+{
+ return m_host_addr;
+}
+
+void *GoldfishAddressSpaceBlock::mmap(uint64_t host_addr)
+{
+ if (m_size == 0) {
+ ALOGE("%s: called with zero size\n", __func__);
+ return NULL;
+ }
+ if (m_mmaped_ptr) {
+ ALOGE("'mmap' called for an already mmaped address block");
+ ::abort();
+ }
+
+ zx_vaddr_t ptr = 0;
+ zx_status_t status = zx_vmar_map(zx_vmar_root_self(),
+ ZX_VM_PERM_READ | ZX_VM_PERM_WRITE,
+ 0, m_vmo,
+ m_offset,
+ m_size,
+ &ptr);
+ if (status != ZX_OK) {
+ ALOGE("%s: host memory map failed with size 0x%llx "
+ "off 0x%llx status %d\n",
+ __func__,
+ (unsigned long long)m_size,
+ (unsigned long long)m_offset, status);
+ return NULL;
+ } else {
+ m_mmaped_ptr = (void*)ptr;
+ m_host_addr = host_addr;
+ return guestPtr();
+ }
+}
+
+void *GoldfishAddressSpaceBlock::guestPtr() const
+{
+ return reinterpret_cast<char *>(m_mmaped_ptr) + (m_host_addr & (PAGE_SIZE - 1));
+}
+
+void GoldfishAddressSpaceBlock::destroy()
+{
+ if (m_mmaped_ptr && m_size) {
+ zx_vmar_unmap(zx_vmar_root_self(),
+ (zx_vaddr_t)m_mmaped_ptr,
+ m_size);
+ m_mmaped_ptr = NULL;
+ }
+
+ if (m_size) {
+ zx_handle_close(m_vmo);
+ m_vmo = ZX_HANDLE_INVALID;
+ m_phys_addr = 0;
+ m_host_addr = 0;
+ m_offset = 0;
+ m_size = 0;
+ }
+}
+
+void GoldfishAddressSpaceBlock::replace(GoldfishAddressSpaceBlock *other)
+{
+ destroy();
+
+ if (other) {
+ *this = *other;
+ *other = GoldfishAddressSpaceBlock();
+ }
+}
+
+bool GoldfishAddressSpaceBlockProvider::is_opened()
+{
+ return m_fd >= 0;
+}
#else
-#ifdef __ANDROID__
#include <linux/types.h>
#include <linux/ioctl.h>
-#elif __Fuchsia__
-typedef uint64_t __u64;
-#define mmap64 mmap
-#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
diff --git a/shared/OpenglCodecCommon/goldfish_address_space.h b/shared/OpenglCodecCommon/goldfish_address_space.h
index 62e74e0..752a723 100644
--- a/shared/OpenglCodecCommon/goldfish_address_space.h
+++ b/shared/OpenglCodecCommon/goldfish_address_space.h
@@ -58,6 +58,9 @@
#ifdef HOST_BUILD
void *m_guest_ptr;
#else
+#ifdef __Fuchsia__
+ uint32_t m_vmo;
+#endif
void *m_mmaped_ptr;
uint64_t m_phys_addr;
uint64_t m_host_addr;
diff --git a/system/vulkan/goldfish_vulkan.cpp b/system/vulkan/goldfish_vulkan.cpp
index c076aa1..b9e2054 100644
--- a/system/vulkan/goldfish_vulkan.cpp
+++ b/system/vulkan/goldfish_vulkan.cpp
@@ -103,6 +103,30 @@
return VK_SUCCESS;
}
+#ifdef VK_USE_PLATFORM_FUCHSIA
+VkResult
+GetMemoryFuchsiaHandleKHR(VkDevice /*device*/,
+ const VkMemoryGetFuchsiaHandleInfoKHR* /*pInfo*/,
+ uint32_t* pHandle) {
+ *pHandle = 0;
+ return VK_SUCCESS;
+}
+
+VkResult
+GetSemaphoreFuchsiaHandleKHR(VkDevice /*device*/,
+ const VkSemaphoreGetFuchsiaHandleInfoKHR* /*pInfo*/,
+ uint32_t* pHandle) {
+ *pHandle = 0;
+ return VK_SUCCESS;
+}
+
+VkResult
+ImportSemaphoreFuchsiaHandleKHR(VkDevice /*device*/,
+ const VkImportSemaphoreFuchsiaHandleInfoKHR* /*pInfo*/) {
+ return VK_SUCCESS;
+}
+#endif
+
PFN_vkVoidFunction GetInstanceProcAddr(VkInstance instance,
const char* name) {
AEMU_SCOPED_TRACE("vkstubhal::GetInstanceProcAddr");
@@ -120,6 +144,14 @@
EnumeratePhysicalDeviceGroups);
if (strcmp(name, "vkGetInstanceProcAddr") == 0)
return reinterpret_cast<PFN_vkVoidFunction>(GetInstanceProcAddr);
+#ifdef VK_USE_PLATFORM_FUCHSIA
+ if (strcmp(name, "vkGetMemoryFuchsiaHandleKHR") == 0)
+ return reinterpret_cast<PFN_vkVoidFunction>(GetMemoryFuchsiaHandleKHR);
+ if (strcmp(name, "vkGetSemaphoreFuchsiaHandleKHR") == 0)
+ return reinterpret_cast<PFN_vkVoidFunction>(GetSemaphoreFuchsiaHandleKHR);
+ if (strcmp(name, "vkImportSemaphoreFuchsiaHandleKHR") == 0)
+ return reinterpret_cast<PFN_vkVoidFunction>(ImportSemaphoreFuchsiaHandleKHR);
+#endif
// Per the spec, return NULL if instance is NULL.
if (!instance)
return nullptr;
@@ -218,6 +250,64 @@
return res;
}
+#ifdef VK_USE_PLATFORM_FUCHSIA
+VKAPI_ATTR
+VkResult GetMemoryFuchsiaHandleKHR(
+ VkDevice device,
+ const VkMemoryGetFuchsiaHandleInfoKHR* pInfo,
+ uint32_t* pHandle) {
+ AEMU_SCOPED_TRACE("goldfish_vulkan::GetMemoryFuchsiaHandleKHR");
+
+ VK_HOST_CONNECTION(VK_ERROR_DEVICE_LOST)
+
+ if (!hostSupportsVulkan) {
+ return vkstubhal::GetMemoryFuchsiaHandleKHR(device, pInfo, pHandle);
+ }
+
+ VkResult res = goldfish_vk::ResourceTracker::get()->
+ on_vkGetMemoryFuchsiaHandleKHR(device, pInfo, pHandle);
+
+ return res;
+}
+
+VKAPI_ATTR
+VkResult GetSemaphoreFuchsiaHandleKHR(
+ VkDevice device,
+ const VkSemaphoreGetFuchsiaHandleInfoKHR* pInfo,
+ uint32_t* pHandle) {
+ AEMU_SCOPED_TRACE("goldfish_vulkan::GetSemaphoreFuchsiaHandleKHR");
+
+ VK_HOST_CONNECTION(VK_ERROR_DEVICE_LOST)
+
+ if (!hostSupportsVulkan) {
+ return vkstubhal::GetSemaphoreFuchsiaHandleKHR(device, pInfo, pHandle);
+ }
+
+ VkResult res = goldfish_vk::ResourceTracker::get()->
+ on_vkGetSemaphoreFuchsiaHandleKHR(device, pInfo, pHandle);
+
+ return res;
+}
+
+VKAPI_ATTR
+VkResult ImportSemaphoreFuchsiaHandleKHR(
+ VkDevice device,
+ const VkImportSemaphoreFuchsiaHandleInfoKHR* pInfo) {
+ AEMU_SCOPED_TRACE("goldfish_vulkan::ImportSemaphoreFuchsiaHandleKHR");
+
+ VK_HOST_CONNECTION(VK_ERROR_DEVICE_LOST)
+
+ if (!hostSupportsVulkan) {
+ return vkstubhal::ImportSemaphoreFuchsiaHandleKHR(device, pInfo);
+ }
+
+ VkResult res = goldfish_vk::ResourceTracker::get()->
+ on_vkImportSemaphoreFuchsiaHandleKHR(device, pInfo);
+
+ return res;
+}
+#endif
+
static PFN_vkVoidFunction GetDeviceProcAddr(VkDevice device, const char* name) {
AEMU_SCOPED_TRACE("goldfish_vulkan::GetDeviceProcAddr");
@@ -227,6 +317,17 @@
return nullptr;
}
+#ifdef VK_USE_PLATFORM_FUCHSIA
+ if (!strcmp(name, "vkGetMemoryFuchsiaHandleKHR")) {
+ return (PFN_vkVoidFunction)GetMemoryFuchsiaHandleKHR;
+ }
+ if (!strcmp(name, "vkGetSemaphoreFuchsiaHandleKHR")) {
+ return (PFN_vkVoidFunction)GetSemaphoreFuchsiaHandleKHR;
+ }
+ if (!strcmp(name, "vkImportSemaphoreFuchsiaHandleKHR")) {
+ return (PFN_vkVoidFunction)ImportSemaphoreFuchsiaHandleKHR;
+ }
+#endif
if (!strcmp(name, "vkGetDeviceProcAddr")) {
return (PFN_vkVoidFunction)(GetDeviceProcAddr);
}
@@ -274,7 +375,21 @@
if (strcmp(id, HWVULKAN_DEVICE_0) == 0) {
*device = &goldfish_vulkan_device.common;
+#ifdef VK_USE_PLATFORM_FUCHSIA
+ goldfish_vk::ResourceTracker::get()->setColorBufferFunctions(
+ [](uint32_t width, uint32_t height, uint32_t format) {
+ VK_HOST_CONNECTION((uint32_t)0)
+ uint32_t r = rcEnc->rcCreateColorBuffer(rcEnc, width, height, format);
+ return r;
+ },
+ [](uint32_t id){
+ VK_HOST_CONNECTION((uint32_t)0)
+ rcEnc->rcCloseColorBuffer(rcEnc, id);
+ return 0u;
+ });
+#else
goldfish_vk::ResourceTracker::get();
+#endif
return 0;
}
return -ENOENT;
diff --git a/system/vulkan_enc/HostVisibleMemoryVirtualization.h b/system/vulkan_enc/HostVisibleMemoryVirtualization.h
index 30ab2f6..10afc46 100644
--- a/system/vulkan_enc/HostVisibleMemoryVirtualization.h
+++ b/system/vulkan_enc/HostVisibleMemoryVirtualization.h
@@ -109,4 +109,4 @@
void subFreeHostMemory(SubAlloc* toFree);
-} // namespace goldfish_vk
\ No newline at end of file
+} // namespace goldfish_vk
diff --git a/system/vulkan_enc/ResourceTracker.cpp b/system/vulkan_enc/ResourceTracker.cpp
index fb99ce3..523ca99 100644
--- a/system/vulkan_enc/ResourceTracker.cpp
+++ b/system/vulkan_enc/ResourceTracker.cpp
@@ -22,6 +22,21 @@
typedef uint32_t zx_handle_t;
#define ZX_HANDLE_INVALID ((zx_handle_t)0)
void zx_handle_close(zx_handle_t) { }
+void zx_event_create(int, zx_handle_t*) { }
+
+typedef struct VkImportMemoryFuchsiaHandleInfoKHR {
+ VkStructureType sType;
+ const void* pNext;
+ VkExternalMemoryHandleTypeFlagBits handleType;
+ uint32_t handle;
+} VkImportMemoryFuchsiaHandleInfoKHR;
+
+#define VK_STRUCTURE_TYPE_IMPORT_MEMORY_FUCHSIA_HANDLE_INFO_KHR \
+ ((VkStructureType)1001000000)
+#define VK_EXTERNAL_MEMORY_HANDLE_TYPE_FUCHSIA_VMO_BIT_KHR \
+ ((VkStructureType)0x00000800)
+#define VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_FUCHSIA_FENCE_BIT_KHR \
+ ((VkStructureType)0x00000020)
#include "AndroidHardwareBuffer.h"
@@ -29,15 +44,52 @@
#ifdef VK_USE_PLATFORM_FUCHSIA
-typedef uint32_t AHardwareBuffer;
-void AHardwareBuffer_release(AHardwareBuffer*) { }
-
+#include <cutils/native_handle.h>
#include <fuchsia/hardware/goldfish/c/fidl.h>
#include <lib/fzl/fdio.h>
#include <zircon/process.h>
#include <zircon/syscalls.h>
#include <zircon/syscalls/object.h>
+struct AHardwareBuffer;
+
+typedef struct VkImportAndroidHardwareBufferInfoANDROID {
+ VkStructureType sType;
+ const void* pNext;
+ struct AHardwareBuffer* buffer;
+} VkImportAndroidHardwareBufferInfoANDROID;
+
+typedef struct VkAndroidHardwareBufferPropertiesANDROID {
+ VkStructureType sType;
+ void* pNext;
+ VkDeviceSize allocationSize;
+ uint32_t memoryTypeBits;
+} VkAndroidHardwareBufferPropertiesANDROID;
+
+void AHardwareBuffer_release(AHardwareBuffer*) { }
+
+native_handle_t *AHardwareBuffer_getNativeHandle(AHardwareBuffer*) { return NULL; }
+
+VkResult importAndroidHardwareBuffer(
+ const VkImportAndroidHardwareBufferInfoANDROID* info,
+ struct AHardwareBuffer **importOut) {
+ return VK_SUCCESS;
+}
+
+VkResult createAndroidHardwareBuffer(
+ bool hasDedicatedImage,
+ bool hasDedicatedBuffer,
+ const VkExtent3D& imageExtent,
+ uint32_t imageLayers,
+ VkFormat imageFormat,
+ VkImageUsageFlags imageUsage,
+ VkImageCreateFlags imageCreateFlags,
+ VkDeviceSize bufferSize,
+ VkDeviceSize allocationInfoAllocSize,
+ struct AHardwareBuffer **out) {
+ return VK_SUCCESS;
+}
+
#endif // VK_USE_PLATFORM_FUCHSIA
#include "HostVisibleMemoryVirtualization.h"
@@ -79,36 +131,6 @@
namespace goldfish_vk {
-namespace {
-
-template<typename T>
-bool GetImportHandle(const void* pNext, VkStructureType import_type,
- uint32_t bit, uint32_t* pHandle) {
- while (pNext) {
- auto info = static_cast<const T*>(pNext);
- if (info->sType == import_type && info->handleType & bit) {
- *pHandle = info->handle;
- return true;
- }
- pNext = info->pNext;
- }
- return false;
-}
-
-template<typename T>
-bool HasExportBit(const void* pNext, VkStructureType export_type, uint32_t bit) {
- while (pNext) {
- auto info = static_cast<const T*>(pNext);
- if (info->sType == export_type && info->handleTypes & bit) {
- return true;
- }
- pNext = info->pNext;
- }
- return false;
-}
-
-} // namespace
-
#define MAKE_HANDLE_MAPPING_FOREACH(type_name, map_impl, map_to_u64_impl, map_from_u64_impl) \
void mapHandles_##type_name(type_name* handles, size_t count) override { \
for (size_t i = 0; i < count; ++i) { \
@@ -207,6 +229,7 @@
VkDeviceMemory currentBacking = VK_NULL_HANDLE;
VkDeviceSize currentBackingOffset = 0;
VkDeviceSize currentBackingSize = 0;
+ uint32_t cbHandle = 0;
};
struct VkBuffer_Info {
@@ -217,6 +240,12 @@
VkDeviceSize currentBackingSize = 0;
};
+ struct VkSemaphore_Info {
+ VkDevice device;
+ zx_handle_t eventHandle = ZX_HANDLE_INVALID;
+ };
+
+
#define HANDLE_REGISTER_IMPL_IMPL(type) \
std::unordered_map<type, type##_Info> info_##type; \
void register_##type(type obj) { \
@@ -265,7 +294,7 @@
AHardwareBuffer_release(memInfo.ahw);
}
- if (memInfo.vmoHandle) {
+ if (memInfo.vmoHandle != ZX_HANDLE_INVALID) {
zx_handle_close(memInfo.vmoHandle);
}
@@ -290,6 +319,11 @@
auto it = info_VkImage.find(img);
if (it == info_VkImage.end()) return;
+ auto& imageInfo = it->second;
+ if (imageInfo.cbHandle) {
+ (*mCloseColorBuffer)(imageInfo.cbHandle);
+ }
+
info_VkImage.erase(img);
}
@@ -302,6 +336,21 @@
info_VkBuffer.erase(buf);
}
+ void unregister_VkSemaphore(VkSemaphore sem) {
+ AutoLock lock(mLock);
+
+ auto it = info_VkSemaphore.find(sem);
+ if (it == info_VkSemaphore.end()) return;
+
+ auto& semInfo = it->second;
+
+ if (semInfo.eventHandle != ZX_HANDLE_INVALID) {
+ zx_handle_close(semInfo.eventHandle);
+ }
+
+ info_VkSemaphore.erase(sem);
+ }
+
// TODO: Upgrade to 1.1
static constexpr uint32_t kMaxApiVersion = VK_MAKE_VERSION(1, 0, 65);
static constexpr uint32_t kMinApiVersion = VK_MAKE_VERSION(1, 0, 0);
@@ -364,6 +413,16 @@
info.vmoHandle = vmoHandle;
}
+ void setImageInfo(VkImage image,
+ VkDevice device,
+ const VkImageCreateInfo *pCreateInfo) {
+ AutoLock lock(mLock);
+ auto& info = info_VkImage[image];
+
+ info.device = device;
+ info.createInfo = *pCreateInfo;
+ }
+
bool isMemoryTypeHostVisible(VkDevice device, uint32_t typeIndex) const {
AutoLock lock(mLock);
const auto it = info_VkDevice.find(device);
@@ -467,6 +526,12 @@
return -1;
}
+ void setColorBufferFunctions(PFN_CreateColorBuffer create,
+ PFN_CloseColorBuffer close) {
+ mCreateColorBuffer = create;
+ mCloseColorBuffer = close;
+ }
+
void deviceMemoryTransform_tohost(
VkDeviceMemory* memory, uint32_t memoryCount,
VkDeviceSize* offset, uint32_t offsetCount,
@@ -628,11 +693,19 @@
}
}
- VkExtensionProperties anbExtProp = {
- "VK_ANDROID_native_buffer", 7,
+ VkExtensionProperties anbExtProps[] = {
+#ifdef VK_USE_PLATFORM_ANDROID_KHR
+ { "VK_ANDROID_native_buffer", 7 },
+#endif
+#ifdef VK_USE_PLATFORM_FUCHSIA
+ { "VK_KHR_external_memory_capabilities", 1},
+ { "VK_KHR_external_semaphore_capabilities", 1},
+#endif
};
- filteredExts.push_back(anbExtProp);
+ for (auto& anbExtProp: anbExtProps) {
+ filteredExts.push_back(anbExtProp);
+ }
if (pPropertyCount) {
*pPropertyCount = filteredExts.size();
@@ -692,11 +765,21 @@
}
}
- VkExtensionProperties anbExtProp = {
- "VK_ANDROID_native_buffer", 7,
+ VkExtensionProperties anbExtProps[] = {
+#ifdef VK_USE_PLATFORM_ANDROID_KHR
+ { "VK_ANDROID_native_buffer", 7 },
+#endif
+#ifdef VK_USE_PLATFORM_FUCHSIA
+ { "VK_KHR_external_memory", 1 },
+ { "VK_KHR_external_memory_fuchsia", 1 },
+ { "VK_KHR_external_semaphore", 1 },
+ { "VK_KHR_external_semaphore_fuchsia", 1 },
+#endif
};
- filteredExts.push_back(anbExtProp);
+ for (auto& anbExtProp: anbExtProps) {
+ filteredExts.push_back(anbExtProp);
+ }
if (pPropertyCount) {
*pPropertyCount = filteredExts.size();
@@ -863,6 +946,7 @@
}
}
+#ifdef VK_USE_PLATFORM_ANDROID_KHR
VkResult on_vkGetAndroidHardwareBufferPropertiesANDROID(
VkDevice device,
const AHardwareBuffer* buffer,
@@ -905,6 +989,116 @@
return queryRes;
}
+#endif
+
+#ifdef VK_USE_PLATFORM_FUCHSIA
+ VkResult on_vkGetMemoryFuchsiaHandleKHR(
+ VkDevice device,
+ const VkMemoryGetFuchsiaHandleInfoKHR* pInfo,
+ uint32_t* pHandle) {
+
+ if (!pInfo) return VK_ERROR_INITIALIZATION_FAILED;
+ if (!pInfo->memory) return VK_ERROR_INITIALIZATION_FAILED;
+
+ AutoLock lock(mLock);
+
+ auto deviceIt = info_VkDevice.find(device);
+
+ if (deviceIt == info_VkDevice.end()) {
+ return VK_ERROR_INITIALIZATION_FAILED;
+ }
+
+ auto memoryIt = info_VkDeviceMemory.find(pInfo->memory);
+
+ if (memoryIt == info_VkDeviceMemory.end()) {
+ return VK_ERROR_INITIALIZATION_FAILED;
+ }
+
+ auto& info = memoryIt->second;
+
+ if (info.vmoHandle == ZX_HANDLE_INVALID) {
+ ALOGE("%s: memory cannot be exported: %d", __func__);
+ return VK_ERROR_INITIALIZATION_FAILED;
+ }
+
+ *pHandle = ZX_HANDLE_INVALID;
+ zx_handle_duplicate(info.vmoHandle, ZX_RIGHT_SAME_RIGHTS, pHandle);
+ return VK_SUCCESS;
+ }
+
+ VkResult on_vkGetMemoryFuchsiaHandlePropertiesKHR(
+ VkDevice device,
+ VkExternalMemoryHandleTypeFlagBitsKHR handleType,
+ uint32_t handle,
+ VkMemoryFuchsiaHandlePropertiesKHR* pProperties) {
+ ALOGW("%s", __FUNCTION__);
+ return VK_ERROR_INITIALIZATION_FAILED;
+ }
+
+ VkResult on_vkImportSemaphoreFuchsiaHandleKHR(
+ VkDevice device,
+ const VkImportSemaphoreFuchsiaHandleInfoKHR* pInfo) {
+
+ if (!pInfo) return VK_ERROR_INITIALIZATION_FAILED;
+ if (!pInfo->semaphore) return VK_ERROR_INITIALIZATION_FAILED;
+
+ AutoLock lock(mLock);
+
+ auto deviceIt = info_VkDevice.find(device);
+
+ if (deviceIt == info_VkDevice.end()) {
+ return VK_ERROR_INITIALIZATION_FAILED;
+ }
+
+ auto semaphoreIt = info_VkSemaphore.find(pInfo->semaphore);
+
+ if (semaphoreIt == info_VkSemaphore.end()) {
+ return VK_ERROR_INITIALIZATION_FAILED;
+ }
+
+ auto& info = semaphoreIt->second;
+
+ if (info.eventHandle != ZX_HANDLE_INVALID) {
+ zx_handle_close(info.eventHandle);
+ }
+ info.eventHandle = pInfo->handle;
+
+ return VK_SUCCESS;
+ }
+
+ VkResult on_vkGetSemaphoreFuchsiaHandleKHR(
+ VkDevice device,
+ const VkSemaphoreGetFuchsiaHandleInfoKHR* pInfo,
+ uint32_t* pHandle) {
+
+ if (!pInfo) return VK_ERROR_INITIALIZATION_FAILED;
+ if (!pInfo->semaphore) return VK_ERROR_INITIALIZATION_FAILED;
+
+ AutoLock lock(mLock);
+
+ auto deviceIt = info_VkDevice.find(device);
+
+ if (deviceIt == info_VkDevice.end()) {
+ return VK_ERROR_INITIALIZATION_FAILED;
+ }
+
+ auto semaphoreIt = info_VkSemaphore.find(pInfo->semaphore);
+
+ if (semaphoreIt == info_VkSemaphore.end()) {
+ return VK_ERROR_INITIALIZATION_FAILED;
+ }
+
+ auto& info = semaphoreIt->second;
+
+ if (info.eventHandle == ZX_HANDLE_INVALID) {
+ return VK_ERROR_INITIALIZATION_FAILED;
+ }
+
+ *pHandle = ZX_HANDLE_INVALID;
+ zx_handle_duplicate(info.eventHandle, ZX_RIGHT_SAME_RIGHTS, pHandle);
+ return VK_SUCCESS;
+ }
+#endif
VkResult on_vkAllocateMemory(
void* context,
@@ -940,8 +1134,9 @@
(VkImportAndroidHardwareBufferInfoANDROID*)vk_find_struct((vk_struct_common*)pAllocateInfo,
VK_STRUCTURE_TYPE_IMPORT_ANDROID_HARDWARE_BUFFER_INFO_ANDROID);
- // TODO: Fuchsia image works in a similar way but over vmo id (phys addr)?
- VkImportPhysicalAddressGOOGLE* importPhysAddrInfoPtr = nullptr;
+ VkImportMemoryFuchsiaHandleInfoKHR* importPhysAddrInfoPtr =
+ (VkImportMemoryFuchsiaHandleInfoKHR*)vk_find_struct((vk_struct_common*)pAllocateInfo,
+ VK_STRUCTURE_TYPE_IMPORT_MEMORY_FUCHSIA_HANDLE_INFO_KHR);
VkMemoryDedicatedAllocateInfo* dedicatedAllocInfoPtr =
(VkMemoryDedicatedAllocateInfo*)vk_find_struct((vk_struct_common*)pAllocateInfo,
@@ -953,7 +1148,7 @@
pAllocateInfo->memoryTypeIndex);
if (!exportAllocateInfoPtr &&
- importAhbInfoPtr && // TODO: Fuchsia image
+ (importAhbInfoPtr || importPhysAddrInfoPtr) &&
dedicatedAllocInfoPtr &&
isHostVisibleMemoryTypeIndexForGuest(
&mHostVisibleMemoryVirtInfo,
@@ -997,12 +1192,12 @@
exportAhb =
exportAllocateInfoPtr->handleTypes &
VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID;
+ exportPhysAddr =
+ exportAllocateInfoPtr->handleTypes &
+ VK_EXTERNAL_MEMORY_HANDLE_TYPE_FUCHSIA_VMO_BIT_KHR;
} else if (importAhbInfoPtr) {
importAhb = true;
- }
-
- if (importPhysAddrInfoPtr) {
- importPhysAddrInfo = *importPhysAddrInfoPtr;
+ } else if (importPhysAddrInfoPtr) {
importPhysAddr = true;
}
@@ -1083,6 +1278,21 @@
vk_append_struct(structChain, (vk_struct_common*)(&importCbInfo));
}
+ if (importPhysAddr) {
+ vmo_handle = importPhysAddrInfoPtr->handle;
+ uint64_t cb = 0;
+
+#ifdef VK_USE_PLATFORM_FUCHSIA
+ zx_object_get_cookie(vmo_handle, vmo_handle, &cb);
+#endif
+
+ if (cb) {
+ importCbInfo.colorBuffer = cb;
+ structChain =
+ vk_append_struct(structChain, (vk_struct_common*)(&importCbInfo));
+ }
+ }
+
// TODO if (exportPhysAddr) { }
if (!isHostVisibleMemoryTypeIndexForGuest(
@@ -1117,6 +1327,13 @@
abort();
}
+ if (vmo_handle != ZX_HANDLE_INVALID) {
+ ALOGE("%s: Host visible export/import allocation "
+ "of VMO is not supported yet.",
+ __func__);
+ abort();
+ }
+
// Host visible memory, non external
bool directMappingSupported = usingDirectMapping();
if (!directMappingSupported) {
@@ -1319,6 +1536,37 @@
VkImage *pImage) {
VkEncoder* enc = (VkEncoder*)context;
+ uint32_t cbHandle = 0;
+
+#ifdef VK_USE_PLATFORM_FUCHSIA
+ VkNativeBufferANDROID native_info = {
+ .sType = VK_STRUCTURE_TYPE_NATIVE_BUFFER_ANDROID,
+ .pNext = NULL,
+ };
+ cb_handle_t native_handle(
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, FRAMEWORK_FORMAT_GL_COMPATIBLE);
+ VkImageCreateInfo localCreateInfo = *pCreateInfo;
+ pCreateInfo = &localCreateInfo;
+
+ if (pCreateInfo->usage &
+ (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
+ VK_IMAGE_USAGE_SCANOUT_BIT_GOOGLE)) {
+ if (localCreateInfo.pNext) {
+ abort();
+ }
+ // Create color buffer.
+ cbHandle = (*mCreateColorBuffer)(localCreateInfo.extent.width,
+ localCreateInfo.extent.height,
+ 0x1908 /*GL_RGBA*/);
+ native_handle.hostHandle = cbHandle;
+ native_info.handle = (uint32_t*)&native_handle;
+ native_info.stride = 0;
+ native_info.format = 1; // RGBA
+ native_info.usage = GRALLOC_USAGE_HW_FB;
+ localCreateInfo.pNext = &native_info;
+ }
+#endif
+
VkResult res = enc->vkCreateImage(device, pCreateInfo, pAllocator, pImage);
if (res != VK_SUCCESS) return res;
@@ -1330,8 +1578,10 @@
auto& info = it->second;
+ info.device = device;
info.createInfo = *pCreateInfo;
info.createInfo.pNext = nullptr;
+ info.cbHandle = cbHandle;
return res;
}
@@ -1371,6 +1621,41 @@
void* context, VkResult,
VkDevice device, VkImage image, VkDeviceMemory memory,
VkDeviceSize memoryOffset) {
+#ifdef VK_USE_PLATFORM_FUCHSIA
+ auto imageIt = info_VkImage.find(image);
+ if (imageIt == info_VkImage.end()) {
+ return VK_ERROR_INITIALIZATION_FAILED;
+ }
+ auto& imageInfo = imageIt->second;
+
+ if (imageInfo.cbHandle) {
+ auto memoryIt = info_VkDeviceMemory.find(memory);
+ if (memoryIt == info_VkDeviceMemory.end()) {
+ return VK_ERROR_INITIALIZATION_FAILED;
+ }
+ auto& memoryInfo = memoryIt->second;
+
+ zx_status_t status;
+ if (memoryInfo.vmoHandle == ZX_HANDLE_INVALID) {
+ status = zx_vmo_create(memoryInfo.allocationSize, 0,
+ &memoryInfo.vmoHandle);
+ if (status != ZX_OK) {
+ ALOGE("%s: failed to alloc vmo", __func__);
+ abort();
+ }
+ }
+ status = zx_object_set_cookie(memoryInfo.vmoHandle,
+ memoryInfo.vmoHandle,
+ imageInfo.cbHandle);
+ if (status != ZX_OK) {
+ ALOGE("%s: failed to set color buffer cookie", __func__);
+ abort();
+ }
+ // Color buffer backed images are already bound.
+ return VK_SUCCESS;
+ }
+#endif
+
VkEncoder* enc = (VkEncoder*)context;
return enc->vkBindImageMemory(device, image, memory, memoryOffset);
}
@@ -1466,13 +1751,46 @@
}
VkResult on_vkCreateSemaphore(
- void* context, VkResult,
+ void* context, VkResult input_result,
VkDevice device, const VkSemaphoreCreateInfo* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkSemaphore* pSemaphore) {
+
VkEncoder* enc = (VkEncoder*)context;
- return enc->vkCreateSemaphore(
+
+ input_result = enc->vkCreateSemaphore(
device, pCreateInfo, pAllocator, pSemaphore);
+
+ if (input_result != VK_SUCCESS) return input_result;
+
+ bool exportFence = false;
+ zx_handle_t event_handle = ZX_HANDLE_INVALID;
+
+ VkExportSemaphoreCreateInfoKHR* exportSemaphoreInfoPtr =
+ (VkExportSemaphoreCreateInfoKHR*)vk_find_struct((vk_struct_common*)pCreateInfo,
+ VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO_KHR);
+
+ if (exportSemaphoreInfoPtr) {
+ exportFence =
+ exportSemaphoreInfoPtr->handleTypes &
+ VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_FUCHSIA_FENCE_BIT_KHR;
+ }
+
+ if (exportFence) {
+ zx_event_create(0, &event_handle);
+ }
+
+ AutoLock lock(mLock);
+
+ auto it = info_VkSemaphore.find(*pSemaphore);
+ if (it == info_VkSemaphore.end()) return VK_ERROR_INITIALIZATION_FAILED;
+
+ auto& info = it->second;
+
+ info.device = device;
+ info.eventHandle = event_handle;
+
+ return VK_SUCCESS;
}
void on_vkDestroySemaphore(
@@ -1483,10 +1801,82 @@
}
VkResult on_vkQueueSubmit(
- void* context, VkResult,
+ void* context, VkResult input_result,
VkQueue queue, uint32_t submitCount, const VkSubmitInfo* pSubmits, VkFence fence) {
+
+ std::vector<VkSemaphore> pre_signal_semaphores;
+ std::vector<zx_handle_t> post_wait_events;
+ VkDevice device = VK_NULL_HANDLE;
+
+#ifdef VK_USE_PLATFORM_FUCHSIA
+ AutoLock lock(mLock);
+
+ for (uint32_t i = 0; i < submitCount; ++i) {
+ for (uint32_t j = 0; j < pSubmits[i].waitSemaphoreCount; ++j) {
+ auto it = info_VkSemaphore.find(pSubmits[i].pWaitSemaphores[j]);
+ if (it != info_VkSemaphore.end()) {
+ auto& semInfo = it->second;
+ if (semInfo.eventHandle) {
+ // Wait here instead of passing semaphore to host.
+ zx_object_wait_one(semInfo.eventHandle,
+ ZX_EVENT_SIGNALED,
+ ZX_TIME_INFINITE,
+ nullptr);
+ pre_signal_semaphores.push_back(pSubmits[i].pWaitSemaphores[j]);
+ }
+ }
+ }
+ for (uint32_t j = 0; j < pSubmits[i].signalSemaphoreCount; ++j) {
+ auto it = info_VkSemaphore.find(pSubmits[i].pSignalSemaphores[j]);
+ if (it != info_VkSemaphore.end()) {
+ auto& semInfo = it->second;
+ if (semInfo.eventHandle) {
+ post_wait_events.push_back(semInfo.eventHandle);
+ device = semInfo.device;
+ }
+ }
+ }
+ }
+ lock.unlock();
+#endif
+
VkEncoder* enc = (VkEncoder*)context;
- return enc->vkQueueSubmit(queue, submitCount, pSubmits, fence);
+
+ VkSubmitInfo submit_info = {
+ .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
+ .waitSemaphoreCount = 0,
+ .pWaitSemaphores = nullptr,
+ .pWaitDstStageMask = nullptr,
+ .signalSemaphoreCount = static_cast<uint32_t>(pre_signal_semaphores.size()),
+ .pSignalSemaphores = pre_signal_semaphores.data()};
+ enc->vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
+
+ input_result = enc->vkQueueSubmit(queue, submitCount, pSubmits, fence);
+
+ if (input_result != VK_SUCCESS) return input_result;
+
+ if (post_wait_events.empty())
+ return VK_SUCCESS;
+
+ VkFenceCreateInfo fence_create_info = {
+ VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, 0, 0,
+ };
+ enc->vkCreateFence(device, &fence_create_info, nullptr, &fence);
+ enc->vkQueueSubmit(queue, 0, nullptr, fence);
+
+ static constexpr uint64_t MAX_WAIT_NS =
+ 5ULL * 1000ULL * 1000ULL * 1000ULL;
+
+ enc->vkWaitForFences(device, 1, &fence, VK_TRUE, MAX_WAIT_NS);
+ enc->vkDestroyFence(device, fence, nullptr);
+
+#ifdef VK_USE_PLATFORM_FUCHSIA
+ for (auto& event : post_wait_events) {
+ zx_object_signal(event, 0, ZX_EVENT_SIGNALED);
+ }
+#endif
+
+ return VK_SUCCESS;
}
void unwrap_VkNativeBufferANDROID(
@@ -1655,6 +2045,8 @@
HostVisibleMemoryVirtualizationInfo mHostVisibleMemoryVirtInfo;
std::unique_ptr<EmulatorFeatureInfo> mFeatureInfo;
std::unique_ptr<GoldfishAddressSpaceBlockProvider> mGoldfishAddressSpaceBlockProvider;
+ PFN_CreateColorBuffer mCreateColorBuffer;
+ PFN_CloseColorBuffer mCloseColorBuffer;
std::vector<VkExtensionProperties> mHostInstanceExtensions;
std::vector<VkExtensionProperties> mHostDeviceExtensions;
@@ -1741,6 +2133,11 @@
return mImpl->hasDeviceExtension(device, name);
}
+void ResourceTracker::setColorBufferFunctions(
+ PFN_CreateColorBuffer create, PFN_CloseColorBuffer close) {
+ mImpl->setColorBufferFunctions(create, close);
+}
+
VkResult ResourceTracker::on_vkEnumerateInstanceVersion(
void* context,
VkResult input_result,
@@ -2022,6 +2419,28 @@
mImpl->unwrap_vkAcquireImageANDROID_nativeFenceFd(fd, fd_out);
}
+#ifdef VK_USE_PLATFORM_FUCHSIA
+VkResult ResourceTracker::on_vkGetMemoryFuchsiaHandleKHR(
+ VkDevice device,
+ const VkMemoryGetFuchsiaHandleInfoKHR* pInfo,
+ uint32_t* pHandle) {
+ return mImpl->on_vkGetMemoryFuchsiaHandleKHR(device, pInfo, pHandle);
+}
+
+VkResult ResourceTracker::on_vkGetSemaphoreFuchsiaHandleKHR(
+ VkDevice device,
+ const VkSemaphoreGetFuchsiaHandleInfoKHR* pInfo,
+ uint32_t* pHandle) {
+ return mImpl->on_vkGetSemaphoreFuchsiaHandleKHR(device, pInfo, pHandle);
+}
+
+VkResult ResourceTracker::on_vkImportSemaphoreFuchsiaHandleKHR(
+ VkDevice device,
+ const VkImportSemaphoreFuchsiaHandleInfoKHR* pInfo) {
+ return mImpl->on_vkImportSemaphoreFuchsiaHandleKHR(device, pInfo);
+}
+#endif
+
VkResult ResourceTracker::on_vkMapMemoryIntoAddressSpaceGOOGLE_pre(
void* context,
VkResult input_result,
diff --git a/system/vulkan_enc/ResourceTracker.h b/system/vulkan_enc/ResourceTracker.h
index 4da1292..1f4d420 100644
--- a/system/vulkan_enc/ResourceTracker.h
+++ b/system/vulkan_enc/ResourceTracker.h
@@ -28,6 +28,9 @@
namespace goldfish_vk {
+typedef uint32_t (*PFN_CreateColorBuffer)(uint32_t width, uint32_t height, uint32_t format);
+typedef uint32_t (*PFN_CloseColorBuffer)(uint32_t id);
+
class ResourceTracker {
public:
ResourceTracker();
@@ -186,7 +189,7 @@
void* context, VkResult input_result,
VkDevice device, uint32_t bindInfoCount, const VkBindBufferMemoryInfo *pBindInfos);
- VkResult on_vkCreateSemaphore(
+ VkResult on_vkCreateSemaphore(
void* context, VkResult,
VkDevice device, const VkSemaphoreCreateInfo* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
@@ -204,6 +207,20 @@
VkImageCreateInfo* local_pCreateInfo);
void unwrap_vkAcquireImageANDROID_nativeFenceFd(int fd, int* fd_out);
+#ifdef VK_USE_PLATFORM_FUCHSIA
+ VkResult on_vkGetMemoryFuchsiaHandleKHR(
+ VkDevice device,
+ const VkMemoryGetFuchsiaHandleInfoKHR* pInfo,
+ uint32_t* pHandle);
+ VkResult on_vkGetSemaphoreFuchsiaHandleKHR(
+ VkDevice device,
+ const VkSemaphoreGetFuchsiaHandleInfoKHR* pInfo,
+ uint32_t* pHandle);
+ VkResult on_vkImportSemaphoreFuchsiaHandleKHR(
+ VkDevice device,
+ const VkImportSemaphoreFuchsiaHandleInfoKHR* pInfo);
+#endif
+
VkResult on_vkMapMemoryIntoAddressSpaceGOOGLE_pre(
void* context,
VkResult input_result,
@@ -229,6 +246,7 @@
uint32_t getApiVersionFromDevice(VkDevice device) const;
bool hasInstanceExtension(VkInstance instance, const std::string& name) const;
bool hasDeviceExtension(VkDevice instance, const std::string& name) const;
+ void setColorBufferFunctions(PFN_CreateColorBuffer create, PFN_CloseColorBuffer close);
// Transforms
void deviceMemoryTransform_tohost(
diff --git a/system/vulkan_enc/VulkanHandles.h b/system/vulkan_enc/VulkanHandles.h
index 2bf601b..2320072 100644
--- a/system/vulkan_enc/VulkanHandles.h
+++ b/system/vulkan_enc/VulkanHandles.h
@@ -41,7 +41,6 @@
f(VkFramebuffer) \
f(VkCommandPool) \
f(VkFence) \
- f(VkSemaphore) \
f(VkEvent) \
f(VkQueryPool) \
f(VkSamplerYcbcrConversion) \
@@ -60,6 +59,7 @@
f(VkDeviceMemory) \
f(VkBuffer) \
f(VkImage) \
+ f(VkSemaphore) \
GOLDFISH_VK_LIST_TRIVIAL_NON_DISPATCHABLE_HANDLE_TYPES(f) \
#define GOLDFISH_VK_LIST_HANDLE_TYPES(f) \