Snap for 5590969 from 2e9eba742d743fd343425cbdb004101a387c17e1 to sdk-release
Change-Id: Ide269cee666f109256280f8aa3d34e438bcb50f9
diff --git a/Android.bp b/Android.bp
new file mode 100644
index 0000000..2f333a0
--- /dev/null
+++ b/Android.bp
@@ -0,0 +1,112 @@
+cc_library_shared {
+ name: "libvulkan_goldfish",
+
+ srcs: [
+ "android-emu/android/base/AlignedBuf.cpp",
+ "android-emu/android/base/Pool.cpp",
+ "android-emu/android/base/SubAllocator.cpp",
+ "android-emu/android/base/files/MemStream.cpp",
+ "android-emu/android/base/files/Stream.cpp",
+ "android-emu/android/base/files/StreamSerializing.cpp",
+ "android-emu/android/base/Tracing.cpp",
+ "shared/OpenglCodecCommon/ChecksumCalculator.cpp",
+ "shared/OpenglCodecCommon/glUtils.cpp",
+ "shared/OpenglCodecCommon/goldfish_address_space.cpp",
+ "shared/OpenglCodecCommon/goldfish_dma.cpp",
+ "system/OpenglSystemCommon/HostConnection.cpp",
+ "system/OpenglSystemCommon/ProcessPipe.cpp",
+ "system/OpenglSystemCommon/ThreadInfo.cpp",
+ "system/renderControl_enc/renderControl_enc.cpp",
+ "system/vulkan/func_table.cpp",
+ "system/vulkan/goldfish_vulkan.cpp",
+ "system/vulkan_enc/HostVisibleMemoryVirtualization.cpp",
+ "system/vulkan_enc/ResourceTracker.cpp",
+ "system/vulkan_enc/Resources.cpp",
+ "system/vulkan_enc/Validation.cpp",
+ "system/vulkan_enc/VkEncoder.cpp",
+ "system/vulkan_enc/VulkanHandleMapping.cpp",
+ "system/vulkan_enc/VulkanStreamGuest.cpp",
+ "system/vulkan_enc/goldfish_vk_deepcopy_guest.cpp",
+ "system/vulkan_enc/goldfish_vk_extension_structs_guest.cpp",
+ "system/vulkan_enc/goldfish_vk_marshaling_guest.cpp",
+ "system/vulkan_enc/goldfish_vk_transform_guest.cpp",
+ ],
+
+ cflags: [
+ "-DLOG_TAG=\"goldfish_vulkan\"",
+ "-DGOLDFISH_VULKAN",
+ "-DGOLDFISH_NO_GL",
+ "-DPAGE_SIZE=4096",
+ "-Wno-unused-parameter",
+ "-Wno-missing-field-initializers",
+ "-Wno-newline-eof",
+ "-Wno-unused-function",
+ "-Wno-unused-value",
+ "-Wno-unused-variable",
+ ],
+
+ include_dirs: [
+ "external/vulkan-headers/include",
+ ],
+
+ local_include_dirs: [
+ "android-emu",
+ "host/include/libOpenglRender",
+ "shared/OpenglCodecCommon",
+ "system/OpenglSystemCommon",
+ "system/renderControl_enc",
+ "system/vulkan_enc",
+ "system/include",
+ ],
+
+ // Only enable on fuchsia.
+ enabled: false,
+ target: {
+ fuchsia: {
+ // TODO(reveman): Enable when not breaking the build.
+ //enabled: true,
+
+ srcs: [
+ "fuchsia/port.cc",
+ "system/OpenglSystemCommon/QemuPipeStreamFuchsia.cpp",
+ ],
+
+ cflags: [
+ "-DVK_USE_PLATFORM_FUCHSIA",
+ "-DPLATFORM_SDK_VERSION=1",
+ "-DFUCHSIA_NO_TRACE",
+ "-DQEMU_PIPE_PATH=\"/dev/class/goldfish-pipe/000\"",
+ "-DGOLDFISH_ADDRESS_SPACE_DEVICE_NAME=\"/dev/class/goldfish-address-space/000\"",
+ ],
+
+ stl: "libc++_static",
+
+ local_include_dirs: [
+ "fuchsia/include",
+ ],
+
+ static_libs: [
+ "libasync",
+ "libfidl",
+ "libfidl_base",
+ "libfidl_cpp",
+ "libfidl_cpp_base",
+ "libfidl_cpp_sync",
+ "libfuchsia.hardware.goldfish.address.space",
+ "libfuchsia.hardware.goldfish.control",
+ "libfuchsia.hardware.goldfish.pipe",
+ "libfuchsia.sysmem",
+ "libzx",
+ ],
+
+ shared_libs: [
+ "libasync-default",
+ "libfdio",
+ ],
+
+ required: [
+ "libzircon",
+ ],
+ },
+ },
+}
diff --git a/BUILD.gn b/BUILD.gn
index fd05f8d..e240ad6 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -1,4 +1,4 @@
-source_set("goldfish_vulkan") {
+shared_library("libvulkan_goldfish") {
sources = [
"android-emu/android/base/AlignedBuf.cpp",
"android-emu/android/base/AlignedBuf.h",
@@ -79,17 +79,25 @@
]
cflags_cc = [
- "-Wno-unused-function",
- "-Wno-unused-variable",
"-Wno-missing-field-initializers",
+ "-Wno-newline-eof",
+ "-Wno-unused-function",
+ "-Wno-unused-value",
+ "-Wno-unused-variable",
]
+ ldflags = [ "-static-libstdc++" ]
+
if (target_os == "fuchsia") {
- sources += [ "fuchsia/port.cc" ]
+ sources -= [ "system/OpenglSystemCommon/QemuPipeStream.cpp" ]
+ sources += [
+ "fuchsia/port.cc",
+ "system/OpenglSystemCommon/QemuPipeStreamFuchsia.cpp",
+ ]
include_dirs += [
- "//third_party/vulkan_loader_and_validation_layers/include",
"fuchsia/include",
+ "//third_party/vulkan_loader_and_validation_layers/include"
]
libs = [
@@ -97,7 +105,9 @@
]
deps = [
- "//zircon/public/fidl/fuchsia-hardware-goldfish-address-space:fuchsia-hardware-goldfish-address-space_c",
+ "//zircon/public/fidl/fuchsia-hardware-goldfish-address-space",
+ "//zircon/public/fidl/fuchsia-hardware-goldfish-control",
+ "//zircon/public/fidl/fuchsia-hardware-goldfish-pipe",
"//zircon/public/fidl/fuchsia-sysmem",
"//zircon/public/lib/fdio",
"//zircon/public/lib/trace",
diff --git a/android-emu/android/base/Tracing.cpp b/android-emu/android/base/Tracing.cpp
index 8b254d2..ff72093 100644
--- a/android-emu/android/base/Tracing.cpp
+++ b/android-emu/android/base/Tracing.cpp
@@ -36,7 +36,9 @@
#elif __Fuchsia__
+#ifndef FUCHSIA_NO_TRACE
#include <trace/event.h>
+#endif
#define VK_TRACE_TAG "gfx"
@@ -44,11 +46,15 @@
namespace base {
void ScopedTrace::beginTraceImpl(const char* name) {
+#ifndef FUCHSIA_NO_TRACE
TRACE_DURATION_BEGIN(VK_TRACE_TAG, name);
+#endif
}
void ScopedTrace::endTraceImpl(const char* name) {
+#ifndef FUCHSIA_NO_TRACE
TRACE_DURATION_END(VK_TRACE_TAG, name);
+#endif
}
} // namespace base
diff --git a/fuchsia/releasepackage.py b/fuchsia/releasepackage.py
new file mode 100644
index 0000000..8f18d68
--- /dev/null
+++ b/fuchsia/releasepackage.py
@@ -0,0 +1,111 @@
+# Copyright 2019 The Fuchsia Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import os
+import sys
+import shutil
+import subprocess
+import argparse
+import re
+
+parser = argparse.ArgumentParser(description="Upload goldfish libvulkan to CIPD")
+
+parser.add_argument("--release-dir")
+parser.add_argument("--arch")
+parser.add_argument("--dry-run", action="store_true")
+parser.add_argument("--ignore-branch", action="store_true")
+parser.add_argument("--ignore-rebuild", action="store_true")
+parser.add_argument("--ignore-buildtype", action="store_true")
+
+args = parser.parse_args()
+
+dir_path = os.path.dirname(os.path.realpath(__file__))
+
+os.chdir(dir_path)
+
+fuchsia_root = os.path.abspath(os.path.join(dir_path, "../../../"))
+
+if args.release_dir:
+ release_dir = os.path.abspath(args.release_dir)
+else:
+ release_dir = os.path.join(fuchsia_root, "out/default")
+
+if not os.path.exists(release_dir):
+ print "Release dir: %s doesn't exist" % release_dir
+ sys.exit(1)
+
+if args.arch:
+ arch = args.arch
+else:
+ arch = "x64"
+
+target_name = "%s-shared/libvulkan_goldfish.so" % arch
+git_repo_location = "%s/third_party/goldfish-opengl" % fuchsia_root
+package_dir = "libvulkan_goldfish/%s" % arch
+package_name = "fuchsia/lib/libvulkan/%s" % package_dir
+
+git_branch = subprocess.check_output([
+ "git", "-C", git_repo_location, "rev-parse", "--abbrev-ref", "HEAD"
+]).strip()
+if git_branch != "master":
+ print("Git repo %s on incorrect branch %s (should be master)" %
+ (repo_name, git_branch))
+ if args.ignore_branch:
+ print("Ignoring")
+ else:
+ print("Use --ignore-branch flag to upload anyway")
+ sys.exit(1)
+
+# Force ninja dry-run
+ninja_output = subprocess.check_output([
+ os.path.join(fuchsia_root, "buildtools/ninja"), "-C", release_dir, "-v",
+ "-n",
+ target_name
+])
+
+if "ninja: no work to do." not in ninja_output:
+ print("Ninja reported work needed to be done for %s" % target_name)
+ if args.ignore_rebuild:
+ print("Ignoring")
+ else:
+ print("Use --ignore-rebuild flag to upload anyway")
+ sys.exit(1)
+
+gn_output = subprocess.check_output([
+ os.path.join(fuchsia_root, "buildtools/gn"), "args", release_dir,
+ "--list=is_debug", "--short"
+]).strip()
+if gn_output != "is_debug = false":
+ print("GN argument \"%s\" unexpected" % gn_output)
+ if args.ignore_buildtype:
+ print("Ignoring")
+ else:
+ print("Use --ignore-buildtype flag to upload anyway")
+ sys.exit(1)
+
+file_name = "libvulkan_goldfish.so"
+full_name = os.path.join(package_dir, file_name)
+
+source_file_name = os.path.join(release_dir, target_name)
+try:
+ os.remove(full_name)
+except:
+ pass
+shutil.copyfile(source_file_name, full_name)
+
+cipd_path = os.path.join(fuchsia_root, "buildtools/cipd")
+git_rev = subprocess.check_output(
+ ["git", "-C", git_repo_location, "rev-parse", "HEAD"]).strip()
+
+cipd_command = "%s create -in %s -name %s -ref latest -tag git_revision:%s" % (
+ cipd_path, package_dir, package_name, git_rev)
+print cipd_command
+if not args.dry_run:
+ subprocess.check_call(cipd_command.split(" "))
+
+print ("""
+ <package name="%s"
+ version="git_revision:%s"
+ path="prebuild/third_party/%s"/>
+""" % (package_name, git_rev, package_dir))[1:-1]
\ No newline at end of file
diff --git a/shared/OpenglCodecCommon/goldfish_address_space.cpp b/shared/OpenglCodecCommon/goldfish_address_space.cpp
index bbc59c6..da6831e 100644
--- a/shared/OpenglCodecCommon/goldfish_address_space.cpp
+++ b/shared/OpenglCodecCommon/goldfish_address_space.cpp
@@ -127,8 +127,9 @@
}
#elif __Fuchsia__
#include <fcntl.h>
-#include <fuchsia/hardware/goldfish/address/space/c/fidl.h>
#include <lib/fdio/fdio.h>
+#include <lib/zx/channel.h>
+#include <lib/zx/vmo.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
@@ -138,17 +139,25 @@
#include <zircon/syscalls/object.h>
GoldfishAddressSpaceBlockProvider::GoldfishAddressSpaceBlockProvider() {
- fdio_get_service_handle(::open(GOLDFISH_ADDRESS_SPACE_DEVICE_NAME, O_RDWR), &m_channel);
+ zx::channel channel;
+ zx_status_t status =
+ fdio_get_service_handle(::open(GOLDFISH_ADDRESS_SPACE_DEVICE_NAME, O_RDWR),
+ channel.reset_and_get_address());
+ if (status != ZX_OK) {
+ ALOGE("%s: failed to get service handle for " GOLDFISH_ADDRESS_SPACE_DEVICE_NAME ": %d",
+ __FUNCTION__, status);
+ return;
+ }
+ m_device.Bind(std::move(channel));
}
GoldfishAddressSpaceBlockProvider::~GoldfishAddressSpaceBlockProvider()
{
- zx_handle_close(m_channel);
}
GoldfishAddressSpaceBlock::GoldfishAddressSpaceBlock()
- : m_vmo(ZX_HANDLE_INVALID)
- , m_channel(ZX_HANDLE_INVALID)
+ : m_device(NULL)
+ , m_vmo(ZX_HANDLE_INVALID)
, m_mmaped_ptr(NULL)
, m_phys_addr(0)
, m_host_addr(0)
@@ -168,7 +177,7 @@
m_host_addr = rhs.m_host_addr;
m_offset = rhs.m_offset;
m_size = rhs.m_size;
- m_channel = rhs.m_channel;
+ m_device = rhs.m_device;
return *this;
}
@@ -184,10 +193,11 @@
return false;
}
+ fuchsia::hardware::goldfish::address::space::DeviceSyncPtr* device = &provider->m_device;
+
int32_t res = ZX_OK;
- zx_status_t status =
- fuchsia_hardware_goldfish_address_space_DeviceAllocateBlock(
- provider->m_channel, size, &res, &m_phys_addr, &m_vmo);
+ zx::vmo vmo;
+ zx_status_t status = (*device)->AllocateBlock(size, &res, &m_phys_addr, &vmo);
if (status != ZX_OK || res != ZX_OK) {
ALOGE("%s: allocate block failed: %d:%d", __func__, status, res);
return false;
@@ -195,12 +205,13 @@
m_offset = 0;
m_size = size;
+ m_vmo = vmo.release();
ALOGD("%s: allocate returned offset 0x%llx size 0x%llx\n", __func__,
(unsigned long long)m_offset,
(unsigned long long)m_size);
- m_channel = provider->m_channel;
+ m_device = device;
return true;
}
@@ -264,13 +275,11 @@
zx_handle_close(m_vmo);
m_vmo = ZX_HANDLE_INVALID;
int32_t res = ZX_OK;
- zx_status_t status =
- fuchsia_hardware_goldfish_address_space_DeviceDeallocateBlock(
- m_channel, m_phys_addr, &res);
+ zx_status_t status = (*m_device)->DeallocateBlock(m_phys_addr, &res);
if (status != ZX_OK || res != ZX_OK) {
ALOGE("%s: deallocate block failed: %d:%d", __func__, status, res);
}
- m_channel = ZX_HANDLE_INVALID;
+ m_device = NULL;
m_phys_addr = 0;
m_host_addr = 0;
m_offset = 0;
@@ -290,7 +299,7 @@
bool GoldfishAddressSpaceBlockProvider::is_opened()
{
- return m_channel != ZX_HANDLE_INVALID;
+ return m_device.is_bound();
}
#else
#include <linux/types.h>
diff --git a/shared/OpenglCodecCommon/goldfish_address_space.h b/shared/OpenglCodecCommon/goldfish_address_space.h
index 7ebb451..250c476 100644
--- a/shared/OpenglCodecCommon/goldfish_address_space.h
+++ b/shared/OpenglCodecCommon/goldfish_address_space.h
@@ -18,6 +18,10 @@
#include <inttypes.h>
#include <stddef.h>
+#ifdef __Fuchsia__
+#include <fuchsia/hardware/goldfish/address/space/cpp/fidl.h>
+#endif
+
class GoldfishAddressSpaceBlock;
#ifdef HOST_BUILD
@@ -46,7 +50,7 @@
bool is_opened();
#ifdef __Fuchsia__
- uint32_t m_channel;
+ fuchsia::hardware::goldfish::address::space::DeviceSyncPtr m_device;
#else
int m_fd;
#endif
@@ -78,8 +82,8 @@
GoldfishAddressSpaceBlockProvider* m_provider;
#else
#ifdef __Fuchsia__
+ fuchsia::hardware::goldfish::address::space::DeviceSyncPtr* m_device;
uint32_t m_vmo;
- uint32_t m_channel;
#else
int m_fd;
#endif
diff --git a/shared/OpenglCodecCommon/gralloc_cb.h b/shared/OpenglCodecCommon/gralloc_cb.h
index ee4bd9a..bff33f3 100644
--- a/shared/OpenglCodecCommon/gralloc_cb.h
+++ b/shared/OpenglCodecCommon/gralloc_cb.h
@@ -32,7 +32,6 @@
FRAMEWORK_FORMAT_GL_COMPATIBLE = 0,
FRAMEWORK_FORMAT_YV12 = 1,
FRAMEWORK_FORMAT_YUV_420_888 = 2, // (Y+)(U+)(V+)
- FRAMEWORK_FORMAT_YUV_420_888_INTERLEAVED = 3, // (Y+)(UV)+
};
//
diff --git a/system/OpenglSystemCommon/ProcessPipe.cpp b/system/OpenglSystemCommon/ProcessPipe.cpp
index ad0527a..5fe9fa3 100644
--- a/system/OpenglSystemCommon/ProcessPipe.cpp
+++ b/system/OpenglSystemCommon/ProcessPipe.cpp
@@ -25,6 +25,12 @@
#include <pthread.h>
#include <errno.h>
+#ifdef __Fuchsia__
+#include <fuchsia/hardware/goldfish/pipe/cpp/fidl.h>
+#include <lib/fdio/fdio.h>
+#include <lib/zx/vmo.h>
+#endif
+
static QEMU_PIPE_HANDLE sProcPipe = 0;
static pthread_once_t sProcPipeOnce = PTHREAD_ONCE_INIT;
// sProcUID is a unique ID per process assigned by the host.
@@ -38,6 +44,79 @@
// It will fallback to the default path if the host does not support it.
// Processes are identified by acquiring a per-process 64bit unique ID from the
// host.
+#ifdef __Fuchsia__
+static void processPipeInitOnce() {
+ int fd = ::open(QEMU_PIPE_PATH, O_RDWR);
+ if (fd < 0) {
+ ALOGE("%s: failed to open " QEMU_PIPE_PATH ": %s",
+ __FUNCTION__, strerror(errno));
+ return;
+ }
+
+ zx::channel channel;
+ zx_status_t status = fdio_get_service_handle(
+ fd, channel.reset_and_get_address());
+ if (status != ZX_OK) {
+ ALOGE("%s: failed to get service handle for " QEMU_PIPE_PATH ": %d",
+ __FUNCTION__, status);
+ close(fd);
+ return;
+ }
+
+ fuchsia::hardware::goldfish::pipe::DeviceSyncPtr device;
+ device.Bind(std::move(channel));
+
+ zx_status_t status2 = ZX_OK;
+ zx::vmo vmo;
+ status = device->GetBuffer(&status2, &vmo);
+ if (status != ZX_OK || status2 != ZX_OK) {
+ ALOGE("%s: failed to get buffer: %d:%d", __FUNCTION__, status, status2);
+ return;
+ }
+
+ size_t len = strlen("pipe:GLProcessPipe");
+ status = vmo.write("pipe:GLProcessPipe", 0, len + 1);
+ if (status != ZX_OK) {
+ ALOGE("%s: failed write pipe name", __FUNCTION__);
+ return;
+ }
+ uint64_t actual;
+ status = device->Write(len + 1, 0, &status2, &actual);
+ if (status != ZX_OK || status2 != ZX_OK) {
+ ALOGD("%s: connecting to pipe service failed: %d:%d", __FUNCTION__,
+ status, status2);
+ return;
+ }
+
+ // Send a confirmation int to the host
+ int32_t confirmInt = 100;
+ status = vmo.write(&confirmInt, 0, sizeof(confirmInt));
+ if (status != ZX_OK) {
+ ALOGE("%s: failed write confirm int", __FUNCTION__);
+ return;
+ }
+ status = device->Write(sizeof(confirmInt), 0, &status2, &actual);
+ if (status != ZX_OK || status2 != ZX_OK) {
+ ALOGD("%s: failed to send confirm value: %d:%d", __FUNCTION__,
+ status, status2);
+ return;
+ }
+
+ // Ask the host for per-process unique ID
+ status = device->Read(sizeof(sProcUID), 0, &status2, &actual);
+ if (status != ZX_OK || status2 != ZX_OK) {
+ ALOGD("%s: failed to recv per-process ID: %d:%d", __FUNCTION__,
+ status, status2);
+ return;
+ }
+ status = vmo.read(&sProcUID, 0, sizeof(sProcUID));
+ if (status != ZX_OK) {
+ ALOGE("%s: failed read per-process ID: %d", __FUNCTION__, status);
+ return;
+ }
+ sProcPipe = device.Unbind().TakeChannel().release();
+}
+#else
static void processPipeInitOnce() {
sProcPipe = qemu_pipe_open("GLProcessPipe");
if (!qemu_pipe_valid(sProcPipe)) {
@@ -76,6 +155,7 @@
return;
}
}
+#endif
bool processPipeInit(renderControl_encoder_context_t *rcEnc) {
pthread_once(&sProcPipeOnce, processPipeInitOnce);
diff --git a/system/OpenglSystemCommon/QemuPipeStream.h b/system/OpenglSystemCommon/QemuPipeStream.h
index 0884d57..a6a3d88 100644
--- a/system/OpenglSystemCommon/QemuPipeStream.h
+++ b/system/OpenglSystemCommon/QemuPipeStream.h
@@ -25,6 +25,12 @@
#include "qemu_pipe.h"
+#ifdef __Fuchsia__
+#include <fuchsia/hardware/goldfish/pipe/cpp/fidl.h>
+#include <lib/zx/event.h>
+#include <lib/zx/vmo.h>
+#endif
+
class QemuPipeStream : public IOStream {
public:
typedef enum { ERR_INVALID_SOCKET = -1000 } QemuPipeStreamError;
@@ -48,6 +54,11 @@
QEMU_PIPE_HANDLE m_sock;
size_t m_bufsize;
unsigned char *m_buf;
+#ifdef __Fuchsia__
+ fuchsia::hardware::goldfish::pipe::DeviceSyncPtr m_device;
+ zx::event m_event;
+ zx::vmo m_vmo;
+#endif
QemuPipeStream(QEMU_PIPE_HANDLE sock, size_t bufSize);
};
diff --git a/system/OpenglSystemCommon/QemuPipeStreamFuchsia.cpp b/system/OpenglSystemCommon/QemuPipeStreamFuchsia.cpp
new file mode 100644
index 0000000..4377d40
--- /dev/null
+++ b/system/OpenglSystemCommon/QemuPipeStreamFuchsia.cpp
@@ -0,0 +1,290 @@
+/*
+* Copyright (C) 2019 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+#include "QemuPipeStream.h"
+
+#include <cutils/log.h>
+#include <errno.h>
+#include <lib/fdio/fdio.h>
+#include <lib/zx/channel.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <zircon/process.h>
+
+#include <utility>
+
+QemuPipeStream::QemuPipeStream(size_t bufSize) :
+ IOStream(bufSize),
+ m_sock(-1),
+ m_bufsize(bufSize),
+ m_buf(nullptr)
+{
+}
+
+QemuPipeStream::QemuPipeStream(QEMU_PIPE_HANDLE sock, size_t bufSize) :
+ IOStream(bufSize),
+ m_sock(sock),
+ m_bufsize(bufSize),
+ m_buf(nullptr)
+{
+}
+
+QemuPipeStream::~QemuPipeStream()
+{
+ if (m_device.is_bound()) {
+ flush();
+ }
+ if (m_buf) {
+ zx_status_t status = zx_vmar_unmap(zx_vmar_root_self(),
+ reinterpret_cast<zx_vaddr_t>(m_buf),
+ m_bufsize);
+ if (status != ZX_OK) {
+ ALOGE("zx_vmar_unmap failed: %d\n", status);
+ abort();
+ }
+ }
+}
+
+int QemuPipeStream::connect(void)
+{
+ int fd = TEMP_FAILURE_RETRY(open(QEMU_PIPE_PATH, O_RDWR));
+ if (fd < 0) {
+ ALOGE("%s: failed to open " QEMU_PIPE_PATH ": %s",
+ __FUNCTION__, strerror(errno));
+ return -1;
+ }
+
+ zx::channel channel;
+ zx_status_t status = fdio_get_service_handle(
+ fd, channel.reset_and_get_address());
+ if (status != ZX_OK) {
+ ALOGE("%s: failed to get service handle for " QEMU_PIPE_PATH ": %d",
+ __FUNCTION__, status);
+ close(fd);
+ return -1;
+ }
+ m_device.Bind(std::move(channel));
+
+ zx::event event;
+ status = zx::event::create(0, &event);
+ if (status != ZX_OK) {
+ ALOGE("%s: failed to create event: %d", __FUNCTION__, status);
+ return -1;
+ }
+ zx::event event_copy;
+ status = event.duplicate(ZX_RIGHT_SAME_RIGHTS, &event_copy);
+ if (status != ZX_OK) {
+ ALOGE("%s: failed to duplicate event: %d", __FUNCTION__, status);
+ return -1;
+ }
+
+ status = m_device->SetEvent(std::move(event_copy));
+ if (status != ZX_OK) {
+ ALOGE("%s: failed to set event: %d:%d", __FUNCTION__, status);
+ return -1;
+ }
+
+ zx_status_t status2 = ZX_OK;
+ zx::vmo vmo;
+ status = m_device->GetBuffer(&status2, &vmo);
+ if (status != ZX_OK || status2 != ZX_OK) {
+ ALOGE("%s: failed to get buffer: %d:%d", __FUNCTION__, status, status2);
+ return -1;
+ }
+
+ size_t len = strlen("pipe:opengles");
+ status = vmo.write("pipe:opengles", 0, len + 1);
+ if (status != ZX_OK) {
+ ALOGE("%s: failed write pipe name", __FUNCTION__);
+ return -1;
+ }
+
+ uint64_t actual;
+ status = m_device->Write(len + 1, 0, &status2, &actual);
+ if (status != ZX_OK || status2 != ZX_OK) {
+ ALOGD("%s: connecting to pipe service failed: %d:%d", __FUNCTION__,
+ status, status2);
+ return -1;
+ }
+
+ m_event = std::move(event);
+ m_vmo = std::move(vmo);
+ return 0;
+}
+
+void *QemuPipeStream::allocBuffer(size_t minSize)
+{
+ zx_status_t status;
+ if (m_buf) {
+ if (minSize <= m_bufsize) {
+ return m_buf;
+ }
+ status = zx_vmar_unmap(zx_vmar_root_self(),
+ reinterpret_cast<zx_vaddr_t>(m_buf),
+ m_bufsize);
+ if (status != ZX_OK) {
+ ALOGE("zx_vmar_unmap failed: %d\n", status);
+ abort();
+ }
+ m_buf = nullptr;
+ }
+
+ size_t allocSize = m_bufsize < minSize ? minSize : m_bufsize;
+
+ zx_status_t status2 = ZX_OK;
+ status = m_device->SetBufferSize(allocSize, &status2);
+ if (status != ZX_OK || status2 != ZX_OK) {
+ ALOGE("%s: failed to get buffer: %d:%d", __FUNCTION__, status, status2);
+ return nullptr;
+ }
+
+ zx::vmo vmo;
+ status = m_device->GetBuffer(&status2, &vmo);
+ if (status != ZX_OK || status2 != ZX_OK) {
+ ALOGE("%s: failed to get buffer: %d:%d", __FUNCTION__, status, status2);
+ return nullptr;
+ }
+
+ zx_vaddr_t mapped_addr;
+ status = zx_vmar_map(zx_vmar_root_self(),
+ ZX_VM_PERM_READ | ZX_VM_PERM_WRITE,
+ 0, vmo.get(), 0, allocSize, &mapped_addr);
+ if (status != ZX_OK) {
+ ALOGE("%s: failed to map buffer: %d:%d", __FUNCTION__, status);
+ return nullptr;
+ }
+
+ m_buf = reinterpret_cast<unsigned char*>(mapped_addr);
+ m_bufsize = allocSize;
+ m_vmo = std::move(vmo);
+ return m_buf;
+}
+
+int QemuPipeStream::commitBuffer(size_t size)
+{
+ if (size == 0) return 0;
+
+ size_t remaining = size;
+ while (remaining) {
+ zx_status_t status2 = ZX_OK;
+ uint64_t actual = 0;
+ zx_status_t status = m_device->Write(
+ remaining, size - remaining, &status2, &actual);
+ if (status != ZX_OK) {
+ ALOGD("%s: Failed writing to pipe: %d", __FUNCTION__, status);
+ return -1;
+ }
+ if (actual) {
+ remaining -= actual;
+ continue;
+ }
+ if (status2 != ZX_ERR_SHOULD_WAIT) {
+ ALOGD("%s: Error writing to pipe: %d", __FUNCTION__, status2);
+ return -1;
+ }
+ zx_signals_t observed = ZX_SIGNAL_NONE;
+ status = m_event.wait_one(
+ fuchsia::hardware::goldfish::pipe::SIGNAL_WRITABLE |
+ fuchsia::hardware::goldfish::pipe::SIGNAL_HANGUP,
+ zx::time::infinite(), &observed);
+ if (status != ZX_OK) {
+ ALOGD("%s: wait_one failed: %d", __FUNCTION__, status);
+ return -1;
+ }
+ if (observed & fuchsia::hardware::goldfish::pipe::SIGNAL_HANGUP) {
+ ALOGD("%s: Remote end hungup", __FUNCTION__);
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+int QemuPipeStream::writeFully(const void *buf, size_t len)
+{
+ ALOGE("%s: unsupported", __FUNCTION__);
+ abort();
+ return -1;
+}
+
+QEMU_PIPE_HANDLE QemuPipeStream::getSocket() const {
+ return m_sock;
+}
+
+const unsigned char *QemuPipeStream::readFully(void *buf, size_t len)
+{
+ if (!m_device.is_bound()) return nullptr;
+
+ if (!buf) {
+ if (len > 0) {
+ ALOGE("QemuPipeStream::readFully failed, buf=NULL, len %zu, lethal"
+ " error, exiting.", len);
+ abort();
+ }
+ return nullptr;
+ }
+
+ size_t remaining = len;
+ while (remaining) {
+ size_t readSize = m_bufsize < remaining ? m_bufsize : remaining;
+ zx_status_t status2 = ZX_OK;
+ uint64_t actual = 0;
+ zx_status_t status = m_device->Read(readSize, 0, &status2, &actual);
+ if (status != ZX_OK) {
+ ALOGD("%s: Failed reading from pipe: %d", __FUNCTION__, status);
+ return nullptr;
+ }
+ if (actual) {
+ m_vmo.read(static_cast<char *>(buf) + (len - remaining), 0, actual);
+ remaining -= actual;
+ continue;
+ }
+ if (status2 != ZX_ERR_SHOULD_WAIT) {
+ ALOGD("%s: Error reading from pipe: %d", __FUNCTION__, status2);
+ return nullptr;
+ }
+ zx_signals_t observed = ZX_SIGNAL_NONE;
+ status = m_event.wait_one(
+ fuchsia::hardware::goldfish::pipe::SIGNAL_READABLE |
+ fuchsia::hardware::goldfish::pipe::SIGNAL_HANGUP,
+ zx::time::infinite(), &observed);
+ if (status != ZX_OK) {
+ ALOGD("%s: wait_one failed: %d", __FUNCTION__, status);
+ return nullptr;
+ }
+ if (observed & fuchsia::hardware::goldfish::pipe::SIGNAL_HANGUP) {
+ ALOGD("%s: Remote end hungup", __FUNCTION__);
+ return nullptr;
+ }
+ }
+
+ return static_cast<const unsigned char *>(buf);
+}
+
+const unsigned char *QemuPipeStream::read(void *buf, size_t *inout_len)
+{
+ ALOGE("%s: unsupported", __FUNCTION__);
+ abort();
+ return nullptr;
+}
+
+int QemuPipeStream::recv(void *buf, size_t len)
+{
+ ALOGE("%s: unsupported", __FUNCTION__);
+ abort();
+ return -1;
+}
diff --git a/system/gralloc/gralloc.cpp b/system/gralloc/gralloc.cpp
index aace8e3..3d08158 100644
--- a/system/gralloc/gralloc.cpp
+++ b/system/gralloc/gralloc.cpp
@@ -114,6 +114,10 @@
typedef std::map<void*, uint32_t> MemRegionMap; // base -> refCount
typedef MemRegionMap::const_iterator mem_region_handle_t;
+ gralloc_memregions_t() {
+ pthread_mutex_init(&lock, NULL);
+ }
+
MemRegionMap ashmemRegions;
pthread_mutex_t lock;
};
@@ -139,10 +143,9 @@
static gralloc_dmaregion_t* s_grdma = NULL;
static gralloc_memregions_t* init_gralloc_memregions() {
- if (s_memregions) return s_memregions;
-
- s_memregions = new gralloc_memregions_t;
- pthread_mutex_init(&s_memregions->lock, NULL);
+ if (!s_memregions) {
+ s_memregions = new gralloc_memregions_t;
+ }
return s_memregions;
}
@@ -479,6 +482,7 @@
bool sw_write = (0 != (usage & GRALLOC_USAGE_SW_WRITE_MASK));
bool hw_write = (usage & GRALLOC_USAGE_HW_RENDER);
bool sw_read = (0 != (usage & GRALLOC_USAGE_SW_READ_MASK));
+ const bool hw_texture = usage & GRALLOC_USAGE_HW_TEXTURE;
#if PLATFORM_SDK_VERSION >= 17
bool hw_cam_write = (usage & GRALLOC_USAGE_HW_CAMERA_WRITE);
bool hw_cam_read = (usage & GRALLOC_USAGE_HW_CAMERA_READ);
@@ -506,10 +510,6 @@
} else if (usage & GRALLOC_USAGE_HW_VIDEO_ENCODER) {
// Camera-to-encoder is NV21
format = HAL_PIXEL_FORMAT_YCrCb_420_SP;
- } else if ((usage & GRALLOC_USAGE_HW_CAMERA_MASK) ==
- GRALLOC_USAGE_HW_CAMERA_ZSL) {
- // Camera-to-ZSL-queue is RGB_888
- format = HAL_PIXEL_FORMAT_RGB_888;
}
}
@@ -546,10 +546,14 @@
glType = GL_UNSIGNED_BYTE;
break;
case HAL_PIXEL_FORMAT_RGB_888:
- bpp = 3;
- glFormat = GL_RGB;
- glType = GL_UNSIGNED_BYTE;
- break;
+ if (hw_texture) {
+ return -EINVAL; // we dont support RGB_888 for HW textures
+ } else {
+ bpp = 3;
+ glFormat = GL_RGB;
+ glType = GL_UNSIGNED_BYTE;
+ break;
+ }
case HAL_PIXEL_FORMAT_RGB_565:
bpp = 2;
// Workaround: distinguish vs the RGB8/RGBA8
@@ -622,13 +626,7 @@
// We are going to use RGB888 on the host
glFormat = GL_RGB;
glType = GL_UNSIGNED_BYTE;
-
- if (usage & (GRALLOC_USAGE_HW_CAMERA_READ | GRALLOC_USAGE_HW_CAMERA_WRITE)) {
- // EmulatedFakeCamera3.cpp assumes it is NV21
- selectedEmuFrameworkFormat = FRAMEWORK_FORMAT_YUV_420_888_INTERLEAVED;
- } else {
- selectedEmuFrameworkFormat = FRAMEWORK_FORMAT_YUV_420_888;
- }
+ selectedEmuFrameworkFormat = FRAMEWORK_FORMAT_YUV_420_888;
break;
default:
ALOGE("gralloc_alloc: Unknown format %d", format);
@@ -1204,7 +1202,9 @@
return -EBUSY;
}
- if (sw_read) {
+ // camera delivers bits to the buffer directly and does not require
+ // an explicit read, it also writes in YUV_420 (interleaved)
+ if (sw_read & !(usage & GRALLOC_USAGE_HW_CAMERA_MASK)) {
void* rgb_addr = cpu_addr;
char* tmpBuf = 0;
if (cb->frameworkFormat == HAL_PIXEL_FORMAT_YV12 ||
@@ -1328,8 +1328,10 @@
return -EINVAL;
}
+ usage |= (cb->usage & GRALLOC_USAGE_HW_CAMERA_MASK);
+
void *vaddr;
- int ret = gralloc_lock(module, handle, usage | GRALLOC_USAGE_SW_WRITE_MASK, l, t, w, h, &vaddr);
+ int ret = gralloc_lock(module, handle, usage, l, t, w, h, &vaddr);
if (ret) {
return ret;
}
@@ -1366,7 +1368,7 @@
cStep = 1;
break;
case HAL_PIXEL_FORMAT_YCbCr_420_888:
- if (cb->emuFrameworkFormat == FRAMEWORK_FORMAT_YUV_420_888_INTERLEAVED) {
+ if (usage & GRALLOC_USAGE_HW_CAMERA_MASK) {
yStride = cb->width;
cStride = cb->width;
yOffset = 0;
diff --git a/system/vulkan/Android.mk b/system/vulkan/Android.mk
index 88118c2..1f32659 100644
--- a/system/vulkan/Android.mk
+++ b/system/vulkan/Android.mk
@@ -20,6 +20,7 @@
$(call emugl-import,libandroidemu)
LOCAL_HEADER_LIBRARIES += \
+ hwvulkan_headers \
vulkan_headers \
endif
diff --git a/system/vulkan/CMakeLists.txt b/system/vulkan/CMakeLists.txt
index e7fd9bb..68a62d6 100644
--- a/system/vulkan/CMakeLists.txt
+++ b/system/vulkan/CMakeLists.txt
@@ -1,7 +1,7 @@
# This is an autogenerated file! Do not edit!
# instead run make from .../device/generic/goldfish-opengl
# which will re-generate this file.
-android_validate_sha256("${GOLDFISH_DEVICE_ROOT}/system/vulkan/Android.mk" "dbe5f184561a1505d6ed26216fe645508b64bf2f3800f67946428077045c8166")
+android_validate_sha256("${GOLDFISH_DEVICE_ROOT}/system/vulkan/Android.mk" "7ec8946bc369a60407913f2257120f701fa2c6e2ce30e3f7148a8e7b0abca46a")
set(vulkan.ranchu_src func_table.cpp goldfish_vulkan.cpp)
android_add_shared_library(vulkan.ranchu)
target_include_directories(vulkan.ranchu PRIVATE ${GOLDFISH_DEVICE_ROOT}/system/OpenglSystemCommon ${GOLDFISH_DEVICE_ROOT}/bionic/libc/private ${GOLDFISH_DEVICE_ROOT}/system/vulkan_enc ${GOLDFISH_DEVICE_ROOT}/android-emu ${GOLDFISH_DEVICE_ROOT}/system/renderControl_enc ${GOLDFISH_DEVICE_ROOT}/system/GLESv2_enc ${GOLDFISH_DEVICE_ROOT}/system/GLESv1_enc ${GOLDFISH_DEVICE_ROOT}/shared/OpenglCodecCommon ${GOLDFISH_DEVICE_ROOT}/system/vulkan ${GOLDFISH_DEVICE_ROOT}/./host/include/libOpenglRender ${GOLDFISH_DEVICE_ROOT}/./system/include ${GOLDFISH_DEVICE_ROOT}/./../../../external/qemu/android/android-emugl/guest ${GOLDFISH_DEVICE_ROOT}/./../../../external/qemu/android/android-emugl/host/include)
diff --git a/system/vulkan/func_table.cpp b/system/vulkan/func_table.cpp
index 14c8c32..f5b380e 100644
--- a/system/vulkan/func_table.cpp
+++ b/system/vulkan/func_table.cpp
@@ -666,7 +666,8 @@
AEMU_SCOPED_TRACE("vkCreateImageView");
auto vkEnc = HostConnection::get()->vkEncoder();
VkResult vkCreateImageView_VkResult_return = (VkResult)0;
- vkCreateImageView_VkResult_return = vkEnc->vkCreateImageView(device, pCreateInfo, pAllocator, pView);
+ auto resources = ResourceTracker::get();
+ vkCreateImageView_VkResult_return = resources->on_vkCreateImageView(vkEnc, VK_SUCCESS, device, pCreateInfo, pAllocator, pView);
return vkCreateImageView_VkResult_return;
}
static void entry_vkDestroyImageView(
@@ -1095,7 +1096,7 @@
}
static void entry_vkCmdSetBlendConstants(
VkCommandBuffer commandBuffer,
- const float blendConstants)
+ const float blendConstants[4])
{
AEMU_SCOPED_TRACE("vkCmdSetBlendConstants");
auto vkEnc = HostConnection::get()->vkEncoder();
diff --git a/system/vulkan/goldfish_vulkan.cpp b/system/vulkan/goldfish_vulkan.cpp
index f133367..f7d288c 100644
--- a/system/vulkan/goldfish_vulkan.cpp
+++ b/system/vulkan/goldfish_vulkan.cpp
@@ -17,6 +17,9 @@
#include <errno.h>
#include <string.h>
+#ifdef VK_USE_PLATFORM_FUCHSIA
+#include <unistd.h>
+#endif
#include "HostConnection.h"
#include "ResourceTracker.h"
@@ -218,6 +221,8 @@
namespace {
+#ifdef VK_USE_PLATFORM_ANDROID_KHR
+
int OpenDevice(const hw_module_t* module, const char* id, hw_device_t** device);
hw_module_methods_t goldfish_vulkan_module_methods = {
@@ -242,6 +247,8 @@
return 0;
}
+#endif
+
#define VK_HOST_CONNECTION(ret) \
HostConnection *hostCon = HostConnection::get(); \
if (!hostCon) { \
@@ -531,6 +538,8 @@
return (PFN_vkVoidFunction)(goldfish_vk::goldfish_vulkan_get_instance_proc_address(instance, name));
}
+#ifdef VK_USE_PLATFORM_ANDROID_KHR
+
hwvulkan_device_t goldfish_vulkan_device = {
.common = {
.tag = HARDWARE_DEVICE_TAG,
@@ -550,27 +559,49 @@
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()
- rcEnc->rcOpenColorBuffer(rcEnc, id);
- },
- [](uint32_t id){
- VK_HOST_CONNECTION()
- rcEnc->rcCloseColorBuffer(rcEnc, id);
- });
-#else
goldfish_vk::ResourceTracker::get();
-#endif
return 0;
}
return -ENOENT;
}
+#endif
+
+#ifdef VK_USE_PLATFORM_FUCHSIA
+
+class VulkanDevice {
+public:
+ VulkanDevice() : mHostSupportsGoldfish(access(QEMU_PIPE_PATH, F_OK) != -1) {
+ goldfish_vk::ResourceTracker::get();
+ }
+
+ static VulkanDevice& GetInstance() {
+ static VulkanDevice g_instance;
+ return g_instance;
+ }
+
+ PFN_vkVoidFunction GetInstanceProcAddr(VkInstance instance, const char* name) {
+ if (!mHostSupportsGoldfish) {
+ return vkstubhal::GetInstanceProcAddr(instance, name);
+ }
+ return ::GetInstanceProcAddr(instance, name);
+ }
+
+private:
+ const bool mHostSupportsGoldfish;
+};
+
+extern "C" __attribute__((visibility("default"))) PFN_vkVoidFunction
+vk_icdGetInstanceProcAddr(VkInstance instance, const char* name) {
+ return VulkanDevice::GetInstance().GetInstanceProcAddr(instance, name);
+}
+
+extern "C" __attribute__((visibility("default"))) VkResult
+vk_icdNegotiateLoaderICDInterfaceVersion(uint32_t* pSupportedVersion) {
+ *pSupportedVersion = std::min(*pSupportedVersion, 3u);
+ return VK_SUCCESS;
+}
+
+#endif
+
} // namespace
diff --git a/system/vulkan_enc/Android.mk b/system/vulkan_enc/Android.mk
index 86d9a4c..c51aa7e 100644
--- a/system/vulkan_enc/Android.mk
+++ b/system/vulkan_enc/Android.mk
@@ -28,6 +28,7 @@
$(LOCAL_PATH)/../vulkan_enc \
LOCAL_HEADER_LIBRARIES += \
+ hwvulkan_headers \
vulkan_headers \
endif
diff --git a/system/vulkan_enc/AndroidHardwareBuffer.cpp b/system/vulkan_enc/AndroidHardwareBuffer.cpp
index a447830..5cebdc2 100644
--- a/system/vulkan_enc/AndroidHardwareBuffer.cpp
+++ b/system/vulkan_enc/AndroidHardwareBuffer.cpp
@@ -59,15 +59,13 @@
VkAndroidHardwareBufferPropertiesANDROID* pProperties) {
VkAndroidHardwareBufferFormatPropertiesANDROID* ahbFormatProps =
- (VkAndroidHardwareBufferFormatPropertiesANDROID*)vk_find_struct(
- (vk_struct_common*)pProperties->pNext,
- VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_ANDROID);
+ vk_find_struct<VkAndroidHardwareBufferFormatPropertiesANDROID>(pProperties);
if (ahbFormatProps) {
AHardwareBuffer_Desc desc;
AHardwareBuffer_describe(buffer, &desc);
- uint64_t gpu_usage =
+ const uint64_t gpu_usage =
AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE |
AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT |
AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER;
@@ -76,10 +74,8 @@
return VK_ERROR_INVALID_EXTERNAL_HANDLE;
}
- ahbFormatProps->format =
- vk_format_from_android(desc.format);
-
- ahbFormatProps->externalFormat = VK_FORMAT_G8B8G8R8_422_UNORM;
+ ahbFormatProps->format = vk_format_from_android(desc.format);
+ ahbFormatProps->externalFormat = desc.format;
// The formatFeatures member must include
// VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT and at least one of
@@ -103,7 +99,10 @@
ahbFormatProps->samplerYcbcrConversionComponents.b = VK_COMPONENT_SWIZZLE_IDENTITY;
ahbFormatProps->samplerYcbcrConversionComponents.a = VK_COMPONENT_SWIZZLE_IDENTITY;
- ahbFormatProps->suggestedYcbcrModel = VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_601;
+ ahbFormatProps->suggestedYcbcrModel =
+ android_format_is_yuv(desc.format) ?
+ VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_601 :
+ VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY;
ahbFormatProps->suggestedYcbcrRange = VK_SAMPLER_YCBCR_RANGE_ITU_FULL;
ahbFormatProps->suggestedXChromaOffset = VK_CHROMA_LOCATION_MIDPOINT;
diff --git a/system/vulkan_enc/CMakeLists.txt b/system/vulkan_enc/CMakeLists.txt
index 9d98562..9d4e7e9 100644
--- a/system/vulkan_enc/CMakeLists.txt
+++ b/system/vulkan_enc/CMakeLists.txt
@@ -1,7 +1,7 @@
# This is an autogenerated file! Do not edit!
# instead run make from .../device/generic/goldfish-opengl
# which will re-generate this file.
-android_validate_sha256("${GOLDFISH_DEVICE_ROOT}/system/vulkan_enc/Android.mk" "694b4f97bb916f16f52b9b2f2287d248de5271e6113ae367cf8bf360637659c5")
+android_validate_sha256("${GOLDFISH_DEVICE_ROOT}/system/vulkan_enc/Android.mk" "4e4982fe274cdee96492d57f444a19d3a979720f17df5d289961d77cbdb4054b")
set(vulkan_enc_src AndroidHardwareBuffer.cpp HostVisibleMemoryVirtualization.cpp Resources.cpp Validation.cpp VulkanStreamGuest.cpp VulkanHandleMapping.cpp ResourceTracker.cpp VkEncoder.cpp goldfish_vk_extension_structs_guest.cpp goldfish_vk_marshaling_guest.cpp goldfish_vk_deepcopy_guest.cpp goldfish_vk_handlemap_guest.cpp goldfish_vk_transform_guest.cpp)
android_add_shared_library(vulkan_enc)
target_include_directories(vulkan_enc PRIVATE ${GOLDFISH_DEVICE_ROOT}/android-emu ${GOLDFISH_DEVICE_ROOT}/shared/OpenglCodecCommon ${GOLDFISH_DEVICE_ROOT}/system/vulkan_enc ${GOLDFISH_DEVICE_ROOT}/./host/include/libOpenglRender ${GOLDFISH_DEVICE_ROOT}/./system/include ${GOLDFISH_DEVICE_ROOT}/./../../../external/qemu/android/android-emugl/guest ${GOLDFISH_DEVICE_ROOT}/./../../../external/qemu/android/android-emugl/host/include ${GOLDFISH_DEVICE_ROOT}/./../../../external/qemu/android/android-emugl/host/include/vulkan)
diff --git a/system/vulkan_enc/ResourceTracker.cpp b/system/vulkan_enc/ResourceTracker.cpp
index 36c2a6b..a81022e 100644
--- a/system/vulkan_enc/ResourceTracker.cpp
+++ b/system/vulkan_enc/ResourceTracker.cpp
@@ -14,6 +14,7 @@
// limitations under the License.
#include "ResourceTracker.h"
+#include "goldfish_vk_private_defs.h"
#include "../OpenglSystemCommon/EmulatorFeatureInfo.h"
@@ -26,31 +27,6 @@
void zx_handle_close(zx_handle_t) { }
void zx_event_create(int, zx_handle_t*) { }
-typedef struct VkImportMemoryZirconHandleInfoFUCHSIA {
- VkStructureType sType;
- const void* pNext;
- VkExternalMemoryHandleTypeFlagBits handleType;
- uint32_t handle;
-} VkImportMemoryZirconHandleInfoFUCHSIA;
-
-typedef uint32_t VkBufferCollectionFUCHSIA;
-
-typedef struct VkImportMemoryBufferCollectionFUCHSIA {
- VkStructureType sType;
- const void* pNext;
- VkBufferCollectionFUCHSIA collection;
- uint32_t index;
-} VkImportMemoryBufferCollectionFUCHSIA;
-
-#define VK_STRUCTURE_TYPE_IMPORT_MEMORY_BUFFER_COLLECTION_FUCHSIA \
- ((VkStructureType)1001000000)
-#define VK_STRUCTURE_TYPE_TEMP_IMPORT_MEMORY_ZIRCON_HANDLE_INFO_FUCHSIA \
- ((VkStructureType)1001000000)
-#define VK_EXTERNAL_MEMORY_HANDLE_TYPE_TEMP_ZIRCON_VMO_BIT_FUCHSIA \
- ((VkStructureType)0x00000800)
-#define VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_TEMP_ZIRCON_EVENT_BIT_FUCHSIA \
- ((VkStructureType)0x00000020)
-
#include "AndroidHardwareBuffer.h"
#endif // VK_USE_PLATFORM_ANDROID_KHR
@@ -58,12 +34,14 @@
#ifdef VK_USE_PLATFORM_FUCHSIA
#include <cutils/native_handle.h>
+#include <fuchsia/hardware/goldfish/control/cpp/fidl.h>
#include <fuchsia/sysmem/cpp/fidl.h>
#include <lib/fdio/directory.h>
#include <lib/fdio/fd.h>
#include <lib/fdio/fdio.h>
#include <lib/fdio/io.h>
#include <lib/zx/channel.h>
+#include <lib/zx/vmo.h>
#include <zircon/process.h>
#include <zircon/syscalls.h>
#include <zircon/syscalls/object.h>
@@ -272,7 +250,6 @@
SubAlloc subAlloc;
AHardwareBuffer* ahw = nullptr;
zx_handle_t vmoHandle = ZX_HANDLE_INVALID;
- uint32_t cbHandle = 0;
};
// custom guest-side structs for images/buffers because of AHardwareBuffer :((
@@ -284,7 +261,6 @@
VkDeviceMemory currentBacking = VK_NULL_HANDLE;
VkDeviceSize currentBackingOffset = 0;
VkDeviceSize currentBackingSize = 0;
- uint32_t cbHandle = 0;
};
struct VkBuffer_Info {
@@ -363,10 +339,6 @@
AHardwareBuffer_release(memInfo.ahw);
}
- if (memInfo.cbHandle) {
- (*mCloseColorBuffer)(memInfo.cbHandle);
- }
-
if (memInfo.vmoHandle != ZX_HANDLE_INVALID) {
zx_handle_close(memInfo.vmoHandle);
}
@@ -393,9 +365,6 @@
if (it == info_VkImage.end()) return;
auto& imageInfo = it->second;
- if (imageInfo.cbHandle) {
- (*mCloseColorBuffer)(imageInfo.cbHandle);
- }
info_VkImage.erase(img);
}
@@ -478,8 +447,7 @@
uint8_t* ptr,
uint32_t memoryTypeIndex,
AHardwareBuffer* ahw = nullptr,
- zx_handle_t vmoHandle = ZX_HANDLE_INVALID,
- uint32_t cbHandle = 0) {
+ zx_handle_t vmoHandle = ZX_HANDLE_INVALID) {
AutoLock lock(mLock);
auto& deviceInfo = info_VkDevice[device];
auto& info = info_VkDeviceMemory[memory];
@@ -490,7 +458,6 @@
info.memoryTypeIndex = memoryTypeIndex;
info.ahw = ahw;
info.vmoHandle = vmoHandle;
- info.cbHandle = cbHandle;
}
void setImageInfo(VkImage image,
@@ -574,11 +541,27 @@
}
#ifdef VK_USE_PLATFORM_FUCHSIA
- zx_status_t status = fdio_service_connect(
- "/svc/fuchsia.sysmem.Allocator",
- mSysmemAllocator.NewRequest().TakeChannel().release());
- if (status != ZX_OK) {
- ALOGE("failed to connect to sysmem service, status %d", status);
+ if (mFeatureInfo->hasVulkan) {
+ int fd = open("/dev/class/goldfish-control/000", O_RDWR);
+ if (fd < 0) {
+ ALOGE("failed to open control device");
+ abort();
+ }
+ zx::channel channel;
+ zx_status_t status = fdio_get_service_handle(fd, channel.reset_and_get_address());
+ if (status != ZX_OK) {
+ ALOGE("failed to get control service handle, status %d", status);
+ abort();
+ }
+ mControlDevice.Bind(std::move(channel));
+
+ status = fdio_service_connect(
+ "/svc/fuchsia.sysmem.Allocator",
+ mSysmemAllocator.NewRequest().TakeChannel().release());
+ if (status != ZX_OK) {
+ ALOGE("failed to get sysmem connection, status %d", status);
+ abort();
+ }
}
#endif
}
@@ -620,14 +603,6 @@
return -1;
}
- void setColorBufferFunctions(PFN_CreateColorBuffer create,
- PFN_OpenColorBuffer open,
- PFN_CloseColorBuffer close) {
- mCreateColorBuffer = create;
- mOpenColorBuffer = open;
- mCloseColorBuffer = close;
- }
-
void deviceMemoryTransform_tohost(
VkDeviceMemory* memory, uint32_t memoryCount,
VkDeviceSize* offset, uint32_t offsetCount,
@@ -1190,9 +1165,6 @@
if (handleType != VK_EXTERNAL_MEMORY_HANDLE_TYPE_TEMP_ZIRCON_VMO_BIT_FUCHSIA) {
return VK_ERROR_INITIALIZATION_FAILED;
}
- if (pProperties->sType != VK_STRUCTURE_TYPE_TEMP_MEMORY_ZIRCON_HANDLE_PROPERTIES_FUCHSIA) {
- return VK_ERROR_INITIALIZATION_FAILED;
- }
AutoLock lock(mLock);
@@ -1318,10 +1290,9 @@
delete sysmem_collection;
}
- VkResult on_vkSetBufferCollectionConstraintsFUCHSIA(
- void*, VkResult, VkDevice,
- VkBufferCollectionFUCHSIA collection,
- const VkImageCreateInfo* pImageInfo) {
+ void setBufferCollectionConstraints(fuchsia::sysmem::BufferCollectionSyncPtr* collection,
+ const VkImageCreateInfo* pImageInfo,
+ size_t min_size_bytes) {
fuchsia::sysmem::BufferCollectionConstraints constraints = {};
constraints.usage.vulkan = fuchsia::sysmem::vulkanUsageColorAttachment |
fuchsia::sysmem::vulkanUsageTransferSrc |
@@ -1331,13 +1302,14 @@
constraints.has_buffer_memory_constraints = true;
fuchsia::sysmem::BufferMemoryConstraints& buffer_constraints =
constraints.buffer_memory_constraints;
- buffer_constraints.min_size_bytes = pImageInfo->extent.width * pImageInfo->extent.height * 4;
+ buffer_constraints.min_size_bytes = min_size_bytes;
buffer_constraints.max_size_bytes = 0xffffffff;
buffer_constraints.physically_contiguous_required = false;
buffer_constraints.secure_required = false;
- buffer_constraints.secure_permitted = false;
- buffer_constraints.ram_domain_supported = true;
+ buffer_constraints.ram_domain_supported = false;
buffer_constraints.cpu_domain_supported = false;
+ buffer_constraints.heap_permitted_count = 1;
+ buffer_constraints.heap_permitted[0] = fuchsia::sysmem::HeapType::Goldfish;
constraints.image_format_constraints_count = 1;
fuchsia::sysmem::ImageFormatConstraints& image_constraints =
constraints.image_format_constraints[0];
@@ -1359,8 +1331,18 @@
image_constraints.display_width_divisor = 1;
image_constraints.display_height_divisor = 1;
- auto sysmem_collection = reinterpret_cast<fuchsia::sysmem::BufferCollectionSyncPtr*>(collection);
- (*sysmem_collection)->SetConstraints(true, constraints);
+ (*collection)->SetConstraints(true, constraints);
+ }
+
+ VkResult on_vkSetBufferCollectionConstraintsFUCHSIA(
+ void*, VkResult, VkDevice,
+ VkBufferCollectionFUCHSIA collection,
+ const VkImageCreateInfo* pImageInfo) {
+ auto sysmem_collection =
+ reinterpret_cast<fuchsia::sysmem::BufferCollectionSyncPtr*>(collection);
+ setBufferCollectionConstraints(
+ sysmem_collection, pImageInfo,
+ pImageInfo->extent.width * pImageInfo->extent.height * 4);
return VK_SUCCESS;
}
@@ -1531,7 +1513,9 @@
VkEncoder* enc = (VkEncoder*)context;
- VkMemoryAllocateInfo finalAllocInfo = *pAllocateInfo;
+ VkMemoryAllocateInfo finalAllocInfo = vk_make_orphan_copy(*pAllocateInfo);
+ vk_struct_chain_iterator structChainIter = vk_make_chain_iterator(&finalAllocInfo);
+
VkMemoryDedicatedAllocateInfo dedicatedAllocInfo;
VkImportColorBufferGOOGLE importCbInfo = {
VK_STRUCTURE_TYPE_IMPORT_COLOR_BUFFER_GOOGLE, 0,
@@ -1540,30 +1524,20 @@
// VK_STRUCTURE_TYPE_IMPORT_PHYSICAL_ADDRESS_GOOGLE, 0,
// };
- vk_struct_common* structChain =
- structChain = vk_init_struct_chain(
- (vk_struct_common*)(&finalAllocInfo));
- structChain->pNext = nullptr;
+ const VkExportMemoryAllocateInfo* exportAllocateInfoPtr =
+ vk_find_struct<VkExportMemoryAllocateInfo>(pAllocateInfo);
- VkExportMemoryAllocateInfo* exportAllocateInfoPtr =
- (VkExportMemoryAllocateInfo*)vk_find_struct((vk_struct_common*)pAllocateInfo,
- VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO);
+ const VkImportAndroidHardwareBufferInfoANDROID* importAhbInfoPtr =
+ vk_find_struct<VkImportAndroidHardwareBufferInfoANDROID>(pAllocateInfo);
- VkImportAndroidHardwareBufferInfoANDROID* importAhbInfoPtr =
- (VkImportAndroidHardwareBufferInfoANDROID*)vk_find_struct((vk_struct_common*)pAllocateInfo,
- VK_STRUCTURE_TYPE_IMPORT_ANDROID_HARDWARE_BUFFER_INFO_ANDROID);
+ const VkImportMemoryBufferCollectionFUCHSIA* importBufferCollectionInfoPtr =
+ vk_find_struct<VkImportMemoryBufferCollectionFUCHSIA>(pAllocateInfo);
- VkImportMemoryBufferCollectionFUCHSIA* importBufferCollectionInfoPtr =
- (VkImportMemoryBufferCollectionFUCHSIA*)vk_find_struct((vk_struct_common*)pAllocateInfo,
- VK_STRUCTURE_TYPE_IMPORT_MEMORY_BUFFER_COLLECTION_FUCHSIA);
+ const VkImportMemoryZirconHandleInfoFUCHSIA* importVmoInfoPtr =
+ vk_find_struct<VkImportMemoryZirconHandleInfoFUCHSIA>(pAllocateInfo);
- VkImportMemoryZirconHandleInfoFUCHSIA* importVmoInfoPtr =
- (VkImportMemoryZirconHandleInfoFUCHSIA*)vk_find_struct((vk_struct_common*)pAllocateInfo,
- VK_STRUCTURE_TYPE_TEMP_IMPORT_MEMORY_ZIRCON_HANDLE_INFO_FUCHSIA);
-
- VkMemoryDedicatedAllocateInfo* dedicatedAllocInfoPtr =
- (VkMemoryDedicatedAllocateInfo*)vk_find_struct((vk_struct_common*)pAllocateInfo,
- VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO);
+ const VkMemoryDedicatedAllocateInfo* dedicatedAllocInfoPtr =
+ vk_find_struct<VkMemoryDedicatedAllocateInfo>(pAllocateInfo);
bool shouldPassThroughDedicatedAllocInfo =
!exportAllocateInfoPtr &&
@@ -1587,12 +1561,8 @@
if (shouldPassThroughDedicatedAllocInfo &&
dedicatedAllocInfoPtr) {
- dedicatedAllocInfo = *dedicatedAllocInfoPtr;
- structChain->pNext =
- (vk_struct_common*)(&dedicatedAllocInfo);
- structChain =
- (vk_struct_common*)(&dedicatedAllocInfo);
- structChain->pNext = nullptr;
+ dedicatedAllocInfo = vk_make_orphan_copy(*dedicatedAllocInfoPtr);
+ vk_append_struct(&structChainIter, &dedicatedAllocInfo);
}
// State needed for import/export.
@@ -1613,8 +1583,6 @@
// and then we attach a new VkDeviceMemory
// to the AHardwareBuffer on the host via an "import" operation.
AHardwareBuffer* ahw = nullptr;
- zx_handle_t vmo_handle = ZX_HANDLE_INVALID;
- uint32_t cbHandle = 0;
if (exportAllocateInfoPtr) {
exportAhb =
@@ -1705,10 +1673,11 @@
const cb_handle_t* cb_handle =
reinterpret_cast<const cb_handle_t*>(handle);
importCbInfo.colorBuffer = cb_handle->hostHandle;
- structChain =
- vk_append_struct(structChain, (vk_struct_common*)(&importCbInfo));
+ vk_append_struct(&structChainIter, &importCbInfo);
}
+ zx_handle_t vmo_handle = ZX_HANDLE_INVALID;
+
if (importBufferCollection) {
#ifdef VK_USE_PLATFORM_FUCHSIA
@@ -1735,35 +1704,105 @@
vmo_handle = importVmoInfoPtr->handle;
}
- if (vmo_handle != ZX_HANDLE_INVALID) {
- uint32_t cb = 0;
-
#ifdef VK_USE_PLATFORM_FUCHSIA
- // TODO(reveman): Remove use of zx_vmo_read. Goldfish FIDL interface
- // should provide a mechanism to query the color buffer ID associated
- // with a VMO.
- zx_status_t status = zx_vmo_read(vmo_handle, &cb, 0, sizeof(cb));
- if (status != ZX_OK) {
- ALOGE("failed to read color buffer name");
- return VK_ERROR_INITIALIZATION_FAILED;
- }
-#endif
+ if (vmo_handle == ZX_HANDLE_INVALID &&
+ !isHostVisibleMemoryTypeIndexForGuest(
+ &mHostVisibleMemoryVirtInfo, finalAllocInfo.memoryTypeIndex)) {
+ bool hasDedicatedImage = dedicatedAllocInfoPtr &&
+ (dedicatedAllocInfoPtr->image != VK_NULL_HANDLE);
+ VkImageCreateInfo imageCreateInfo = {};
- if (cb) {
- cbHandle = importCbInfo.colorBuffer = cb;
- structChain =
- vk_append_struct(structChain, (vk_struct_common*)(&importCbInfo));
+ if (hasDedicatedImage) {
+ AutoLock lock(mLock);
+
+ auto it = info_VkImage.find(dedicatedAllocInfoPtr->image);
+ if (it == info_VkImage.end()) return VK_ERROR_INITIALIZATION_FAILED;
+ const auto& imageInfo = it->second;
+
+ imageCreateInfo = imageInfo.createInfo;
+ }
+
+ if (imageCreateInfo.usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) {
+ fuchsia::sysmem::BufferCollectionTokenSyncPtr token;
+ zx_status_t status = mSysmemAllocator->AllocateSharedCollection(
+ token.NewRequest());
+ if (status != ZX_OK) {
+ ALOGE("AllocateSharedCollection failed: %d", status);
+ abort();
+ }
+
+ fuchsia::sysmem::BufferCollectionSyncPtr collection;
+ status = mSysmemAllocator->BindSharedCollection(
+ std::move(token), collection.NewRequest());
+ if (status != ZX_OK) {
+ ALOGE("BindSharedCollection failed: %d", status);
+ abort();
+ }
+ setBufferCollectionConstraints(&collection,
+ &imageCreateInfo,
+ finalAllocInfo.allocationSize);
+
+ fuchsia::sysmem::BufferCollectionInfo_2 info;
+ zx_status_t status2;
+ status = collection->WaitForBuffersAllocated(&status2, &info);
+ if (status == ZX_OK && status2 == ZX_OK) {
+ if (!info.buffer_count) {
+ ALOGE("WaitForBuffersAllocated returned invalid count: %d", status);
+ abort();
+ }
+ vmo_handle = info.buffers[0].vmo.release();
+ } else {
+ ALOGE("WaitForBuffersAllocated failed: %d %d", status, status2);
+ abort();
+ }
+
+ collection->Close();
+
+ zx::vmo vmo_copy;
+ status = zx_handle_duplicate(vmo_handle,
+ ZX_RIGHT_SAME_RIGHTS,
+ vmo_copy.reset_and_get_address());
+ if (status != ZX_OK) {
+ ALOGE("Failed to duplicate VMO: %d", status);
+ abort();
+ }
+ status = mControlDevice->CreateColorBuffer(
+ std::move(vmo_copy),
+ imageCreateInfo.extent.width,
+ imageCreateInfo.extent.height,
+ fuchsia::hardware::goldfish::control::FormatType::BGRA,
+ &status2);
+ if (status != ZX_OK || status2 != ZX_OK) {
+ ALOGE("CreateColorBuffer failed: %d:%d", status, status2);
+ abort();
+ }
}
}
+ if (vmo_handle != ZX_HANDLE_INVALID) {
+ zx::vmo vmo_copy;
+ zx_status_t status = zx_handle_duplicate(vmo_handle,
+ ZX_RIGHT_SAME_RIGHTS,
+ vmo_copy.reset_and_get_address());
+ if (status != ZX_OK) {
+ ALOGE("Failed to duplicate VMO: %d", status);
+ abort();
+ }
+ zx_status_t status2 = ZX_OK;
+ status = mControlDevice->GetColorBuffer(
+ std::move(vmo_copy), &status2, &importCbInfo.colorBuffer);
+ if (status != ZX_OK || status2 != ZX_OK) {
+ ALOGE("GetColorBuffer failed: %d:%d", status, status2);
+ }
+ vk_append_struct(&structChainIter, &importCbInfo);
+ }
+#endif
+
// TODO if (exportVmo) { }
if (!isHostVisibleMemoryTypeIndexForGuest(
&mHostVisibleMemoryVirtInfo,
finalAllocInfo.memoryTypeIndex)) {
- if (cbHandle) {
- (*mOpenColorBuffer)(cbHandle);
- }
input_result =
enc->vkAllocateMemory(
device, &finalAllocInfo, pAllocator, pMemory);
@@ -1777,8 +1816,7 @@
0, nullptr,
finalAllocInfo.memoryTypeIndex,
ahw,
- vmo_handle,
- cbHandle);
+ vmo_handle);
return VK_SUCCESS;
}
@@ -2051,10 +2089,7 @@
transformExternalResourceMemoryRequirementsForGuest(&reqs2->memoryRequirements);
VkMemoryDedicatedRequirements* dedicatedReqs =
- (VkMemoryDedicatedRequirements*)
- vk_find_struct(
- (vk_struct_common*)reqs2,
- VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS);
+ vk_find_struct<VkMemoryDedicatedRequirements>(reqs2);
if (!dedicatedReqs) return;
@@ -2083,10 +2118,7 @@
transformExternalResourceMemoryRequirementsForGuest(&reqs2->memoryRequirements);
VkMemoryDedicatedRequirements* dedicatedReqs =
- (VkMemoryDedicatedRequirements*)
- vk_find_struct(
- (vk_struct_common*)reqs2,
- VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS);
+ vk_find_struct<VkMemoryDedicatedRequirements>(reqs2);
if (!dedicatedReqs) return;
@@ -2101,164 +2133,90 @@
VkImage *pImage) {
VkEncoder* enc = (VkEncoder*)context;
- uint32_t cbHandle = 0;
-
- VkImageCreateInfo localCreateInfo = *pCreateInfo;
- VkNativeBufferANDROID localAnb;
+ VkImageCreateInfo localCreateInfo = vk_make_orphan_copy(*pCreateInfo);
+ vk_struct_chain_iterator structChainIter = vk_make_chain_iterator(&localCreateInfo);
VkExternalMemoryImageCreateInfo localExtImgCi;
- VkImageCreateInfo* pCreateInfo_mut = &localCreateInfo;
-
- VkNativeBufferANDROID* anbInfoPtr =
- (VkNativeBufferANDROID*)
- vk_find_struct(
- (vk_struct_common*)pCreateInfo_mut,
- VK_STRUCTURE_TYPE_NATIVE_BUFFER_ANDROID);
-
- if (anbInfoPtr) {
- localAnb = *anbInfoPtr;
- }
-
- VkExternalMemoryImageCreateInfo* extImgCiPtr =
- (VkExternalMemoryImageCreateInfo*)
- vk_find_struct(
- (vk_struct_common*)pCreateInfo_mut,
- VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO);
-
+ const VkExternalMemoryImageCreateInfo* extImgCiPtr =
+ vk_find_struct<VkExternalMemoryImageCreateInfo>(pCreateInfo);
if (extImgCiPtr) {
- localExtImgCi = *extImgCiPtr;
+ localExtImgCi = vk_make_orphan_copy(*extImgCiPtr);
+ vk_append_struct(&structChainIter, &localExtImgCi);
}
#ifdef VK_USE_PLATFORM_ANDROID_KHR
+ VkNativeBufferANDROID localAnb;
+ const VkNativeBufferANDROID* anbInfoPtr =
+ vk_find_struct<VkNativeBufferANDROID>(pCreateInfo);
+ if (anbInfoPtr) {
+ localAnb = vk_make_orphan_copy(*anbInfoPtr);
+ vk_append_struct(&structChainIter, &localAnb);
+ }
+
VkExternalFormatANDROID localExtFormatAndroid;
- VkExternalFormatANDROID* extFormatAndroidPtr =
- (VkExternalFormatANDROID*)
- vk_find_struct(
- (vk_struct_common*)pCreateInfo_mut,
- VK_STRUCTURE_TYPE_EXTERNAL_FORMAT_ANDROID);
+ const VkExternalFormatANDROID* extFormatAndroidPtr =
+ vk_find_struct<VkExternalFormatANDROID>(pCreateInfo);
if (extFormatAndroidPtr) {
- localExtFormatAndroid = *extFormatAndroidPtr;
- }
-#endif
+ localExtFormatAndroid = vk_make_orphan_copy(*extFormatAndroidPtr);
-#ifdef VK_USE_PLATFORM_FUCHSIA
- VkFuchsiaImageFormatFUCHSIA* extFuchsiaImageFormatPtr =
- (VkFuchsiaImageFormatFUCHSIA*)
- vk_find_struct(
- (vk_struct_common*)pCreateInfo_mut,
- VK_STRUCTURE_TYPE_FUCHSIA_IMAGE_FORMAT_FUCHSIA);
-
- VkBufferCollectionImageCreateInfoFUCHSIA* extBufferCollectionPtr =
- (VkBufferCollectionImageCreateInfoFUCHSIA*)
- vk_find_struct(
- (vk_struct_common*)pCreateInfo_mut,
- VK_STRUCTURE_TYPE_BUFFER_COLLECTION_IMAGE_CREATE_INFO_FUCHSIA);
-#endif
-
- vk_struct_common* structChain =
- vk_init_struct_chain((vk_struct_common*)pCreateInfo_mut);
-
- if (extImgCiPtr) {
- structChain =
- vk_append_struct(
- structChain, (vk_struct_common*)(&localExtImgCi));
- }
-
-#ifdef VK_USE_PLATFORM_ANDROID_KHR
- if (anbInfoPtr) {
- structChain =
- vk_append_struct(
- structChain, (vk_struct_common*)(&localAnb));
- }
-
- if (extFormatAndroidPtr) {
// Do not append external format android;
- // instead, replace the local image pCreateInfo_mut format
+ // instead, replace the local image localCreateInfo format
// with the corresponding Vulkan format
if (extFormatAndroidPtr->externalFormat) {
- pCreateInfo_mut->format =
+ localCreateInfo.format =
vk_format_from_android(extFormatAndroidPtr->externalFormat);
+ if (localCreateInfo.format == VK_FORMAT_UNDEFINED)
+ return VK_ERROR_VALIDATION_FAILED_EXT;
}
}
#endif
-
#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);
+ const VkBufferCollectionImageCreateInfoFUCHSIA* extBufferCollectionPtr =
+ vk_find_struct<VkBufferCollectionImageCreateInfoFUCHSIA>(pCreateInfo);
+ if (extBufferCollectionPtr) {
+ auto collection = reinterpret_cast<fuchsia::sysmem::BufferCollectionSyncPtr*>(
+ extBufferCollectionPtr->collection);
+ uint32_t index = extBufferCollectionPtr->index;
+ zx::vmo vmo;
- if (pCreateInfo->usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) {
- // Create color buffer.
- cbHandle = (*mCreateColorBuffer)(pCreateInfo_mut->extent.width,
- pCreateInfo_mut->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;
- if (pCreateInfo_mut->pNext) {
- abort();
- }
- pCreateInfo_mut->pNext = &native_info;
-
- bool is_physically_contiguous = false;
- if (extBufferCollectionPtr) {
- auto collection = reinterpret_cast<fuchsia::sysmem::BufferCollectionSyncPtr*>(
- extBufferCollectionPtr->collection);
- fuchsia::sysmem::BufferCollectionInfo_2 info;
- zx_status_t status2;
- zx_status_t status = (*collection)->WaitForBuffersAllocated(&status2, &info);
- if (status == ZX_OK && status2 == ZX_OK) {
- is_physically_contiguous =
- info.settings.has_image_format_constraints &&
- info.settings.buffer_settings.is_physically_contiguous;
- } else {
- ALOGE("WaitForBuffersAllocated failed: %d %d", status, status2);
- }
- } else if (extFuchsiaImageFormatPtr) {
- auto imageFormat = static_cast<const uint8_t*>(
- extFuchsiaImageFormatPtr->imageFormat);
- size_t imageFormatSize =
- extFuchsiaImageFormatPtr->imageFormatSize;
- std::vector<uint8_t> message(
- imageFormat, imageFormat + imageFormatSize);
- fidl::Message msg(fidl::BytePart(message.data(),
- imageFormatSize,
- imageFormatSize),
- fidl::HandlePart());
- const char* err_msg = nullptr;
- zx_status_t status = msg.Decode(
- fuchsia::sysmem::SingleBufferSettings::FidlType, &err_msg);
- if (status != ZX_OK) {
- ALOGE("Invalid SingleBufferSettings: %d %s", status,
- err_msg);
- abort();
+ fuchsia::sysmem::BufferCollectionInfo_2 info;
+ zx_status_t status2;
+ zx_status_t status = (*collection)->WaitForBuffersAllocated(&status2, &info);
+ if (status == ZX_OK && status2 == ZX_OK) {
+ if (index < info.buffer_count) {
+ vmo = std::move(info.buffers[index].vmo);
}
- fidl::Decoder decoder(std::move(msg));
- fuchsia::sysmem::SingleBufferSettings settings;
- fuchsia::sysmem::SingleBufferSettings::Decode(
- &decoder, &settings, 0);
- is_physically_contiguous =
- settings.buffer_settings.is_physically_contiguous;
+ } else {
+ ALOGE("WaitForBuffersAllocated failed: %d %d", status, status2);
}
- if (is_physically_contiguous) {
- // Replace the local image pCreateInfo_mut format
- // with the color buffer format if physically contiguous
- // and a potential display layer candidate.
- // TODO(reveman): Remove this after adding BGRA color
- // buffer support.
- pCreateInfo_mut->format = VK_FORMAT_R8G8B8A8_UNORM;
+ if (vmo.is_valid()) {
+ zx_status_t status2 = ZX_OK;
+ status = mControlDevice->CreateColorBuffer(
+ std::move(vmo),
+ localCreateInfo.extent.width,
+ localCreateInfo.extent.height,
+ fuchsia::hardware::goldfish::control::FormatType::BGRA,
+ &status2);
+ if (status != ZX_OK || status2 != ZX_OK) {
+ ALOGE("CreateColorBuffer failed: %d:%d", status, status2);
+ }
+ }
+ }
+
+ // Allow external memory for all color attachments on fuchsia.
+ if (localCreateInfo.usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) {
+ if (!extImgCiPtr) {
+ localExtImgCi.sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO;
+ localExtImgCi.pNext = nullptr;
+ localExtImgCi.handleTypes = ~0; // handle type just needs to be non-zero
+ extImgCiPtr = &localExtImgCi; // no vk_append_struct required
}
}
#endif
- VkResult res = enc->vkCreateImage(device, pCreateInfo_mut, pAllocator, pImage);
+ VkResult res = enc->vkCreateImage(device, &localCreateInfo, pAllocator, pImage);
if (res != VK_SUCCESS) return res;
@@ -2270,9 +2228,8 @@
auto& info = it->second;
info.device = device;
- info.createInfo = *pCreateInfo_mut;
+ info.createInfo = *pCreateInfo;
info.createInfo.pNext = nullptr;
- info.cbHandle = cbHandle;
if (!extImgCiPtr) return res;
@@ -2289,28 +2246,14 @@
const VkAllocationCallbacks* pAllocator,
VkSamplerYcbcrConversion* pYcbcrConversion) {
- VkSamplerYcbcrConversionCreateInfo localCreateInfo = *pCreateInfo;
- VkSamplerYcbcrConversionCreateInfo* pCreateInfo_mut = &localCreateInfo;
+ VkSamplerYcbcrConversionCreateInfo localCreateInfo = vk_make_orphan_copy(*pCreateInfo);
#ifdef VK_USE_PLATFORM_ANDROID_KHR
- VkExternalFormatANDROID localExtFormatAndroid;
- VkExternalFormatANDROID* extFormatAndroidPtr =
- (VkExternalFormatANDROID*)
- vk_find_struct(
- (vk_struct_common*)pCreateInfo_mut,
- VK_STRUCTURE_TYPE_EXTERNAL_FORMAT_ANDROID);
- if (extFormatAndroidPtr) {
- localExtFormatAndroid = *extFormatAndroidPtr;
- }
-#endif
-
- vk_struct_common* structChain =
- vk_init_struct_chain((vk_struct_common*)pCreateInfo_mut);
-
-#ifdef VK_USE_PLATFORM_ANDROID_KHR
+ const VkExternalFormatANDROID* extFormatAndroidPtr =
+ vk_find_struct<VkExternalFormatANDROID>(pCreateInfo);
if (extFormatAndroidPtr) {
if (extFormatAndroidPtr->externalFormat) {
- pCreateInfo_mut->format =
+ localCreateInfo.format =
vk_format_from_android(extFormatAndroidPtr->externalFormat);
}
}
@@ -2318,7 +2261,7 @@
VkEncoder* enc = (VkEncoder*)context;
return enc->vkCreateSamplerYcbcrConversion(
- device, pCreateInfo, pAllocator, pYcbcrConversion);
+ device, &localCreateInfo, pAllocator, pYcbcrConversion);
}
VkResult on_vkCreateSamplerYcbcrConversionKHR(
@@ -2328,34 +2271,22 @@
const VkAllocationCallbacks* pAllocator,
VkSamplerYcbcrConversion* pYcbcrConversion) {
- VkSamplerYcbcrConversionCreateInfo localCreateInfo = *pCreateInfo;
- VkSamplerYcbcrConversionCreateInfo* pCreateInfo_mut = &localCreateInfo;
+ VkSamplerYcbcrConversionCreateInfo localCreateInfo = vk_make_orphan_copy(*pCreateInfo);
#ifdef VK_USE_PLATFORM_ANDROID_KHR
- VkExternalFormatANDROID localExtFormatAndroid;
- VkExternalFormatANDROID* extFormatAndroidPtr =
- (VkExternalFormatANDROID*)
- vk_find_struct(
- (vk_struct_common*)pCreateInfo_mut,
- VK_STRUCTURE_TYPE_EXTERNAL_FORMAT_ANDROID);
+ const VkExternalFormatANDROID* extFormatAndroidPtr =
+ vk_find_struct<VkExternalFormatANDROID>(pCreateInfo);
if (extFormatAndroidPtr) {
- localExtFormatAndroid = *extFormatAndroidPtr;
- }
-#endif
-
- vk_struct_common* structChain =
- vk_init_struct_chain((vk_struct_common*)pCreateInfo_mut);
-
-#ifdef VK_USE_PLATFORM_ANDROID_KHR
- if (extFormatAndroidPtr) {
- pCreateInfo_mut->format =
- vk_format_from_android(extFormatAndroidPtr->externalFormat);
+ if (extFormatAndroidPtr->externalFormat) {
+ localCreateInfo.format =
+ vk_format_from_android(extFormatAndroidPtr->externalFormat);
+ }
}
#endif
VkEncoder* enc = (VkEncoder*)context;
return enc->vkCreateSamplerYcbcrConversionKHR(
- device, pCreateInfo, pAllocator, pYcbcrConversion);
+ device, &localCreateInfo, pAllocator, pYcbcrConversion);
}
void on_vkDestroyImage(
@@ -2399,42 +2330,6 @@
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();
- }
- }
- // TODO(reveman): Remove use of zx_vmo_write. Sysmem
- // and goldfish pipe driver should manage this association.
- status = zx_vmo_write(memoryInfo.vmoHandle, &imageInfo.cbHandle,
- 0, sizeof(imageInfo.cbHandle));
- if (status != ZX_OK) {
- ALOGE("%s: failed writing color buffer id to vmo", __func__);
- abort();
- }
- // Color buffer backed images are already bound.
- return VK_SUCCESS;
- }
-#endif
-
VkEncoder* enc = (VkEncoder*)context;
return enc->vkBindImageMemory(device, image, memory, memoryOffset);
}
@@ -2474,9 +2369,8 @@
info.createInfo = *pCreateInfo;
info.createInfo.pNext = nullptr;
- VkExternalMemoryBufferCreateInfo* extBufCi =
- (VkExternalMemoryBufferCreateInfo*)vk_find_struct((vk_struct_common*)pCreateInfo,
- VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO);
+ const VkExternalMemoryBufferCreateInfo* extBufCi =
+ vk_find_struct<VkExternalMemoryBufferCreateInfo>(pCreateInfo);
if (!extBufCi) return res;
@@ -2566,10 +2460,8 @@
VkSemaphoreCreateInfo finalCreateInfo = *pCreateInfo;
- VkExportSemaphoreCreateInfoKHR* exportSemaphoreInfoPtr =
- (VkExportSemaphoreCreateInfoKHR*)vk_find_struct(
- (vk_struct_common*)pCreateInfo,
- VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO_KHR);
+ const VkExportSemaphoreCreateInfoKHR* exportSemaphoreInfoPtr =
+ vk_find_struct<VkExportSemaphoreCreateInfoKHR>(pCreateInfo);
#ifdef VK_USE_PLATFORM_FUCHSIA
bool exportEvent = exportSemaphoreInfoPtr &&
@@ -3138,9 +3030,7 @@
(void)input_result;
VkAndroidHardwareBufferUsageANDROID* output_ahw_usage =
- (VkAndroidHardwareBufferUsageANDROID*)vk_find_struct(
- (vk_struct_common*)pImageFormatProperties,
- VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_USAGE_ANDROID);
+ vk_find_struct<VkAndroidHardwareBufferUsageANDROID>(pImageFormatProperties);
VkResult hostRes;
@@ -3233,6 +3123,32 @@
return VK_SUCCESS;
}
+ VkResult on_vkCreateImageView(
+ void* context, VkResult input_result,
+ VkDevice device,
+ const VkImageViewCreateInfo* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkImageView* pView) {
+
+ VkEncoder* enc = (VkEncoder*)context;
+ (void)input_result;
+
+ VkImageViewCreateInfo localCreateInfo = vk_make_orphan_copy(*pCreateInfo);
+
+#ifdef VK_USE_PLATFORM_ANDROID_KHR
+ const VkExternalFormatANDROID* extFormatAndroidPtr =
+ vk_find_struct<VkExternalFormatANDROID>(pCreateInfo);
+ if (extFormatAndroidPtr) {
+ if (extFormatAndroidPtr->externalFormat) {
+ localCreateInfo.format =
+ vk_format_from_android(extFormatAndroidPtr->externalFormat);
+ }
+ }
+#endif
+
+ return enc->vkCreateImageView(device, &localCreateInfo, pAllocator, pView);
+ }
+
uint32_t getApiVersionFromInstance(VkInstance instance) const {
AutoLock lock(mLock);
uint32_t api = kMinApiVersion;
@@ -3283,9 +3199,6 @@
HostVisibleMemoryVirtualizationInfo mHostVisibleMemoryVirtInfo;
std::unique_ptr<EmulatorFeatureInfo> mFeatureInfo;
std::unique_ptr<GoldfishAddressSpaceBlockProvider> mGoldfishAddressSpaceBlockProvider;
- PFN_CreateColorBuffer mCreateColorBuffer;
- PFN_OpenColorBuffer mOpenColorBuffer;
- PFN_CloseColorBuffer mCloseColorBuffer;
std::vector<VkExtensionProperties> mHostInstanceExtensions;
std::vector<VkExtensionProperties> mHostDeviceExtensions;
@@ -3293,6 +3206,7 @@
int mSyncDeviceFd = -1;
#ifdef VK_USE_PLATFORM_FUCHSIA
+ fuchsia::hardware::goldfish::control::DeviceSyncPtr mControlDevice;
fuchsia::sysmem::AllocatorSyncPtr mSysmemAllocator;
#endif
};
@@ -3378,13 +3292,6 @@
return mImpl->hasDeviceExtension(device, name);
}
-void ResourceTracker::setColorBufferFunctions(
- PFN_CreateColorBuffer create,
- PFN_OpenColorBuffer open,
- PFN_CloseColorBuffer close) {
- mImpl->setColorBufferFunctions(create, open, close);
-}
-
VkResult ResourceTracker::on_vkEnumerateInstanceExtensionProperties(
void* context,
VkResult input_result,
@@ -3883,6 +3790,16 @@
context, input_result, commandBuffer, flags);
}
+VkResult ResourceTracker::on_vkCreateImageView(
+ void* context, VkResult input_result,
+ VkDevice device,
+ const VkImageViewCreateInfo* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkImageView* pView) {
+ return mImpl->on_vkCreateImageView(
+ context, input_result, device, pCreateInfo, pAllocator, pView);
+}
+
void ResourceTracker::deviceMemoryTransform_tohost(
VkDeviceMemory* memory, uint32_t memoryCount,
VkDeviceSize* offset, uint32_t offsetCount,
diff --git a/system/vulkan_enc/ResourceTracker.h b/system/vulkan_enc/ResourceTracker.h
index e3189e4..6429d6f 100644
--- a/system/vulkan_enc/ResourceTracker.h
+++ b/system/vulkan_enc/ResourceTracker.h
@@ -28,10 +28,6 @@
namespace goldfish_vk {
-typedef uint32_t (*PFN_CreateColorBuffer)(uint32_t width, uint32_t height, uint32_t format);
-typedef void (*PFN_OpenColorBuffer)(uint32_t id);
-typedef void (*PFN_CloseColorBuffer)(uint32_t id);
-
class ResourceTracker {
public:
ResourceTracker();
@@ -338,6 +334,13 @@
VkCommandBuffer commandBuffer,
VkCommandBufferResetFlags flags);
+ VkResult on_vkCreateImageView(
+ void* context, VkResult input_result,
+ VkDevice device,
+ const VkImageViewCreateInfo* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkImageView* pView);
+
bool isMemoryTypeHostVisible(VkDevice device, uint32_t typeIndex) const;
uint8_t* getMappedPointer(VkDeviceMemory memory);
VkDeviceSize getMappedSize(VkDeviceMemory memory);
@@ -350,9 +353,6 @@
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_OpenColorBuffer open,
- PFN_CloseColorBuffer close);
// Transforms
void deviceMemoryTransform_tohost(
diff --git a/system/vulkan_enc/VkEncoder.cpp b/system/vulkan_enc/VkEncoder.cpp
index b97f120..42487ea 100644
--- a/system/vulkan_enc/VkEncoder.cpp
+++ b/system/vulkan_enc/VkEncoder.cpp
@@ -7137,7 +7137,7 @@
void VkEncoder::vkCmdSetBlendConstants(
VkCommandBuffer commandBuffer,
- const float blendConstants)
+ const float blendConstants[4])
{
AEMU_SCOPED_TRACE("vkCmdSetBlendConstants encode");
mImpl->log("start vkCmdSetBlendConstants");
diff --git a/system/vulkan_enc/VkEncoder.h b/system/vulkan_enc/VkEncoder.h
index 16df497..8328b32 100644
--- a/system/vulkan_enc/VkEncoder.h
+++ b/system/vulkan_enc/VkEncoder.h
@@ -473,7 +473,7 @@
float depthBiasSlopeFactor);
void vkCmdSetBlendConstants(
VkCommandBuffer commandBuffer,
- const float blendConstants);
+ const float blendConstants[4]);
void vkCmdSetDepthBounds(
VkCommandBuffer commandBuffer,
float minDepthBounds,
diff --git a/system/vulkan_enc/goldfish_vk_private_defs.h b/system/vulkan_enc/goldfish_vk_private_defs.h
index 3eed244..35d4425 100644
--- a/system/vulkan_enc/goldfish_vk_private_defs.h
+++ b/system/vulkan_enc/goldfish_vk_private_defs.h
@@ -425,6 +425,104 @@
VkCommandBuffer commandBuffer,
VkCommandBufferResetFlags flags);
+#ifndef VK_FUCHSIA_buffer_collection
+#define VK_FUCHSIA_buffer_collection 1
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkBufferCollectionFUCHSIA)
+
+#define VK_FUCHSIA_BUFFER_COLLECTION_SPEC_VERSION 1
+#define VK_FUCHSIA_BUFFER_COLLECTION_EXTENSION_NAME "VK_FUCHSIA_buffer_collection"
+
+typedef struct VkBufferCollectionCreateInfoFUCHSIA {
+ VkStructureType sType;
+ const void* pNext;
+ uint32_t collectionToken;
+} VkBufferCollectionCreateInfoFUCHSIA;
+
+typedef struct VkImportMemoryBufferCollectionFUCHSIA {
+ VkStructureType sType;
+ const void* pNext;
+ VkBufferCollectionFUCHSIA collection;
+ uint32_t index;
+} VkImportMemoryBufferCollectionFUCHSIA;
+
+typedef struct VkBufferCollectionImageCreateInfoFUCHSIA {
+ VkStructureType sType;
+ const void* pNext;
+ VkBufferCollectionFUCHSIA collection;
+ uint32_t index;
+} VkBufferCollectionImageCreateInfoFUCHSIA;
+
+typedef struct VkBufferCollectionPropertiesFUCHSIA {
+ VkStructureType sType;
+ void* pNext;
+ uint32_t memoryTypeBits;
+ uint32_t count;
+} VkBufferCollectionPropertiesFUCHSIA;
+
+#define VK_STRUCTURE_TYPE_IMPORT_MEMORY_BUFFER_COLLECTION_FUCHSIA \
+ ((VkStructureType)1001004004)
+#define VK_STRUCTURE_TYPE_BUFFER_COLLECTION_IMAGE_CREATE_INFO_FUCHSIA \
+ ((VkStructureType)1001004005)
+#endif // VK_FUCHSIA_buffer_collection
+
+#ifndef VK_FUCHSIA_external_memory
+#define VK_FUCHSIA_external_memory 1
+#define VK_FUCHSIA_EXTERNAL_MEMORY_SPEC_VERSION 1
+#define VK_FUCHSIA_EXTERNAL_MEMORY_EXTENSION_NAME "VK_FUCHSIA_external_memory"
+
+typedef struct VkImportMemoryZirconHandleInfoFUCHSIA {
+ VkStructureType sType;
+ const void* pNext;
+ VkExternalMemoryHandleTypeFlagBits handleType;
+ uint32_t handle;
+} VkImportMemoryZirconHandleInfoFUCHSIA;
+
+typedef struct VkMemoryZirconHandlePropertiesFUCHSIA {
+ VkStructureType sType;
+ void* pNext;
+ uint32_t memoryTypeBits;
+} VkMemoryZirconHandlePropertiesFUCHSIA;
+
+typedef struct VkMemoryGetZirconHandleInfoFUCHSIA {
+ VkStructureType sType;
+ const void* pNext;
+ VkDeviceMemory memory;
+ VkExternalMemoryHandleTypeFlagBits handleType;
+} VkMemoryGetZirconHandleInfoFUCHSIA;
+
+#define VK_STRUCTURE_TYPE_TEMP_IMPORT_MEMORY_ZIRCON_HANDLE_INFO_FUCHSIA \
+ ((VkStructureType)1001005000)
+#define VK_STRUCTURE_TYPE_TEMP_MEMORY_ZIRCON_HANDLE_PROPERTIES_FUCHSIA \
+ ((VkStructureType)1001005001)
+#define VK_EXTERNAL_MEMORY_HANDLE_TYPE_TEMP_ZIRCON_VMO_BIT_FUCHSIA \
+ ((VkExternalMemoryHandleTypeFlagBits)0x00100000)
+#endif // VK_FUCHSIA_external_memory
+
+#ifndef VK_FUCHSIA_external_semaphore
+#define VK_FUCHSIA_external_semaphore 1
+#define VK_FUCHSIA_EXTERNAL_SEMAPHORE_SPEC_VERSION 1
+#define VK_FUCHSIA_EXTERNAL_SEMAPHORE_EXTENSION_NAME "VK_FUCHSIA_external_semaphore"
+
+typedef struct VkImportSemaphoreZirconHandleInfoFUCHSIA {
+ VkStructureType sType;
+ const void* pNext;
+ VkSemaphore semaphore;
+ VkSemaphoreImportFlags flags;
+ VkExternalSemaphoreHandleTypeFlagBits handleType;
+ uint32_t handle;
+} VkImportSemaphoreZirconHandleInfoFUCHSIA;
+
+typedef struct VkSemaphoreGetZirconHandleInfoFUCHSIA {
+ VkStructureType sType;
+ const void* pNext;
+ VkSemaphore semaphore;
+ VkExternalSemaphoreHandleTypeFlagBits handleType;
+} VkSemaphoreGetZirconHandleInfoFUCHSIA;
+
+#define VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_TEMP_ZIRCON_EVENT_BIT_FUCHSIA \
+ ((VkExternalSemaphoreHandleTypeFlagBits)0x00100000)
+#endif // VK_FUCHSIA_external_semaphore
+
#ifdef __cplusplus
} // extern "C"
#endif
diff --git a/system/vulkan_enc/vk_format_info.h b/system/vulkan_enc/vk_format_info.h
index 3bac828..c70f45f 100644
--- a/system/vulkan_enc/vk_format_info.h
+++ b/system/vulkan_enc/vk_format_info.h
@@ -58,7 +58,7 @@
}
static inline unsigned
-android_format_from_vk(unsigned vk_format)
+android_format_from_vk(VkFormat vk_format)
{
switch (vk_format) {
case VK_FORMAT_R8G8B8A8_UNORM:
@@ -78,6 +78,18 @@
}
}
+static inline bool
+android_format_is_yuv(unsigned android_format)
+{
+ switch (android_format) {
+ case HAL_PIXEL_FORMAT_NV12_Y_TILED_INTEL:
+ return true;
+
+ default:
+ return false;
+ }
+}
+
static inline VkImageAspectFlags
vk_format_aspects(VkFormat format)
{
diff --git a/system/vulkan_enc/vk_struct_id.h b/system/vulkan_enc/vk_struct_id.h
new file mode 100644
index 0000000..561b430
--- /dev/null
+++ b/system/vulkan_enc/vk_struct_id.h
@@ -0,0 +1,50 @@
+// Copyright (C) 2018 The Android Open Source Project
+// Copyright (C) 2018 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+#pragma once
+
+#include <vulkan/vulkan.h>
+#include "goldfish_vk_private_defs.h"
+
+template <class T> struct vk_get_vk_struct_id;
+
+#define REGISTER_VK_STRUCT_ID(T, ID) \
+ template <> struct vk_get_vk_struct_id<T> { static constexpr VkStructureType id = ID; };
+
+REGISTER_VK_STRUCT_ID(VkAndroidHardwareBufferPropertiesANDROID, VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_PROPERTIES_ANDROID);
+REGISTER_VK_STRUCT_ID(VkAndroidHardwareBufferFormatPropertiesANDROID, VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_ANDROID);
+REGISTER_VK_STRUCT_ID(VkAndroidHardwareBufferUsageANDROID, VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_USAGE_ANDROID);
+REGISTER_VK_STRUCT_ID(VkBufferCreateInfo, VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO);
+REGISTER_VK_STRUCT_ID(VkImageCreateInfo, VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO);
+REGISTER_VK_STRUCT_ID(VkImageFormatProperties2, VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2);
+REGISTER_VK_STRUCT_ID(VkNativeBufferANDROID, VK_STRUCTURE_TYPE_NATIVE_BUFFER_ANDROID);
+REGISTER_VK_STRUCT_ID(VkExternalFormatANDROID, VK_STRUCTURE_TYPE_EXTERNAL_FORMAT_ANDROID);
+REGISTER_VK_STRUCT_ID(VkExternalMemoryBufferCreateInfo, VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO);
+REGISTER_VK_STRUCT_ID(VkExternalMemoryImageCreateInfo, VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO);
+REGISTER_VK_STRUCT_ID(VkMemoryAllocateInfo, VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO);
+REGISTER_VK_STRUCT_ID(VkMemoryDedicatedAllocateInfo, VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO);
+REGISTER_VK_STRUCT_ID(VkMemoryDedicatedRequirements, VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS);
+REGISTER_VK_STRUCT_ID(VkImportAndroidHardwareBufferInfoANDROID, VK_STRUCTURE_TYPE_IMPORT_ANDROID_HARDWARE_BUFFER_INFO_ANDROID);
+REGISTER_VK_STRUCT_ID(VkExportMemoryAllocateInfo, VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO);
+REGISTER_VK_STRUCT_ID(VkMemoryRequirements2, VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2);
+REGISTER_VK_STRUCT_ID(VkSemaphoreCreateInfo, VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO);
+REGISTER_VK_STRUCT_ID(VkExportSemaphoreCreateInfoKHR, VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO_KHR);
+REGISTER_VK_STRUCT_ID(VkSamplerYcbcrConversionCreateInfo, VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO);
+REGISTER_VK_STRUCT_ID(VkImportColorBufferGOOGLE, VK_STRUCTURE_TYPE_IMPORT_COLOR_BUFFER_GOOGLE);
+REGISTER_VK_STRUCT_ID(VkImageViewCreateInfo, VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO);
+REGISTER_VK_STRUCT_ID(VkImportMemoryBufferCollectionFUCHSIA, VK_STRUCTURE_TYPE_IMPORT_MEMORY_BUFFER_COLLECTION_FUCHSIA);
+REGISTER_VK_STRUCT_ID(VkImportMemoryZirconHandleInfoFUCHSIA, VK_STRUCTURE_TYPE_TEMP_IMPORT_MEMORY_ZIRCON_HANDLE_INFO_FUCHSIA);
+REGISTER_VK_STRUCT_ID(VkBufferCollectionImageCreateInfoFUCHSIA, VK_STRUCTURE_TYPE_BUFFER_COLLECTION_IMAGE_CREATE_INFO_FUCHSIA);
+
+#undef REGISTER_VK_STRUCT_ID
diff --git a/system/vulkan_enc/vk_util.h b/system/vulkan_enc/vk_util.h
index 0c7f4b9..39de991 100644
--- a/system/vulkan_enc/vk_util.h
+++ b/system/vulkan_enc/vk_util.h
@@ -26,12 +26,18 @@
/* common inlines and macros for vulkan drivers */
#include <vulkan/vulkan.h>
+#include <stdlib.h>
+#include "vk_struct_id.h"
struct vk_struct_common {
VkStructureType sType;
struct vk_struct_common *pNext;
};
+struct vk_struct_chain_iterator {
+ vk_struct_common* value;
+};
+
#define vk_foreach_struct(__iter, __start) \
for (struct vk_struct_common *__iter = (struct vk_struct_common *)(__start); \
__iter; __iter = __iter->pNext)
@@ -191,11 +197,18 @@
return NULL;
}
-#define vk_find_struct(__start, __sType) \
- __vk_find_struct((__start), __sType)
+template <class T, class H> T* vk_find_struct(H* head)
+{
+ vk_get_vk_struct_id<H>::id;
+ return static_cast<T*>(__vk_find_struct(static_cast<void*>(head), vk_get_vk_struct_id<T>::id));
+}
-#define vk_find_struct_const(__start, __sType) \
- (const void *)__vk_find_struct((void *)(__start), __sType)
+template <class T, class H> const T* vk_find_struct(const H* head)
+{
+ vk_get_vk_struct_id<H>::id;
+ return static_cast<const T*>(__vk_find_struct(const_cast<void*>(static_cast<const void*>(head)),
+ vk_get_vk_struct_id<T>::id));
+}
uint32_t vk_get_driver_version(void);
@@ -207,19 +220,32 @@
#define VK_ENUM_OFFSET(__enum) \
((__enum) >= VK_EXT_OFFSET ? ((__enum) % 1000) : (__enum))
-static inline vk_struct_common*
-vk_init_struct_chain(vk_struct_common* start)
-{
- start->pNext = nullptr;
- return start;
+template <class T> T vk_make_orphan_copy(const T& vk_struct) {
+ T copy = vk_struct;
+ copy.pNext = NULL;
+ return copy;
}
-static inline vk_struct_common*
-vk_append_struct(vk_struct_common* current, vk_struct_common* next)
+template <class T> vk_struct_chain_iterator vk_make_chain_iterator(T* vk_struct)
{
- current->pNext = next;
- next->pNext = nullptr;
- return next;
+ vk_get_vk_struct_id<T>::id;
+ vk_struct_chain_iterator result = { reinterpret_cast<vk_struct_common*>(vk_struct) };
+ return result;
+}
+
+template <class T> void vk_append_struct(vk_struct_chain_iterator* i, T* vk_struct)
+{
+ vk_get_vk_struct_id<T>::id;
+
+ vk_struct_common* p = i->value;
+ if (p->pNext) {
+ ::abort();
+ }
+
+ p->pNext = reinterpret_cast<vk_struct_common *>(vk_struct);
+ vk_struct->pNext = NULL;
+
+ *i = vk_make_chain_iterator(vk_struct);
}
#endif /* VK_UTIL_H */