Snap for 5519018 from f78f995bf290b3e3427dabf3b28b08b71445bc89 to qt-release
Change-Id: I33aea8d373b9c752df1a121b0ebcb5a064e3006b
diff --git a/BUILD.gn b/BUILD.gn
index 1f50018..348ab87 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -87,7 +87,11 @@
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",
@@ -101,6 +105,7 @@
deps = [
"//zircon/public/fidl/fuchsia-hardware-goldfish-address-space:fuchsia-hardware-goldfish-address-space_c",
"//zircon/public/fidl/fuchsia-hardware-goldfish-control:fuchsia-hardware-goldfish-control_c",
+ "//zircon/public/fidl/fuchsia-hardware-goldfish-pipe:fuchsia-hardware-goldfish-pipe_c",
"//zircon/public/fidl/fuchsia-sysmem",
"//zircon/public/lib/fdio",
"//zircon/public/lib/trace",
diff --git a/system/OpenglSystemCommon/QemuPipeStream.h b/system/OpenglSystemCommon/QemuPipeStream.h
index 0884d57..8d64ab8 100644
--- a/system/OpenglSystemCommon/QemuPipeStream.h
+++ b/system/OpenglSystemCommon/QemuPipeStream.h
@@ -25,6 +25,12 @@
#include "qemu_pipe.h"
+#ifdef __Fuchsia__
+#include <lib/zx/channel.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__
+ zx::channel m_channel;
+ 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..f4ee61c
--- /dev/null
+++ b/system/OpenglSystemCommon/QemuPipeStreamFuchsia.cpp
@@ -0,0 +1,296 @@
+/*
+* 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 <fuchsia/hardware/goldfish/pipe/c/fidl.h>
+#include <lib/fdio/fdio.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_channel.is_valid()) {
+ 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;
+ }
+
+ 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 = fuchsia_hardware_goldfish_pipe_DeviceSetEvent(
+ channel.get(), event_copy.release());
+ 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 = fuchsia_hardware_goldfish_pipe_DeviceGetBuffer(
+ channel.get(), &status2, vmo.reset_and_get_address());
+ 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 = fuchsia_hardware_goldfish_pipe_DeviceWrite(
+ channel.get(), 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_channel = std::move(channel);
+ 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 = fuchsia_hardware_goldfish_pipe_DeviceSetBufferSize(
+ m_channel.get(), 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 = fuchsia_hardware_goldfish_pipe_DeviceGetBuffer(
+ m_channel.get(), &status2, vmo.reset_and_get_address());
+ 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 = fuchsia_hardware_goldfish_pipe_DeviceWrite(
+ m_channel.get(), 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_channel.is_valid()) 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 = fuchsia_hardware_goldfish_pipe_DeviceRead(
+ m_channel.get(), 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/vulkan_enc/AndroidHardwareBuffer.cpp b/system/vulkan_enc/AndroidHardwareBuffer.cpp
index 05f14f1..516791b 100644
--- a/system/vulkan_enc/AndroidHardwareBuffer.cpp
+++ b/system/vulkan_enc/AndroidHardwareBuffer.cpp
@@ -59,8 +59,8 @@
VkAndroidHardwareBufferPropertiesANDROID* pProperties) {
VkAndroidHardwareBufferFormatPropertiesANDROID* ahbFormatProps =
- (VkAndroidHardwareBufferFormatPropertiesANDROID*)vk_find_struct(
- (vk_struct_common*)pProperties->pNext,
+ vk_find_struct<VkAndroidHardwareBufferFormatPropertiesANDROID>(
+ pProperties,
VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_ANDROID);
if (ahbFormatProps) {
@@ -76,7 +76,7 @@
return VK_ERROR_INVALID_EXTERNAL_HANDLE;
}
- ahbFormatProps->format = VK_FORMAT_UNDEFINED;
+ ahbFormatProps->format = vk_format_from_android(desc.format);
ahbFormatProps->externalFormat = desc.format;
// The formatFeatures member must include
diff --git a/system/vulkan_enc/ResourceTracker.cpp b/system/vulkan_enc/ResourceTracker.cpp
index 631f24d..3b5bdb8 100644
--- a/system/vulkan_enc/ResourceTracker.cpp
+++ b/system/vulkan_enc/ResourceTracker.cpp
@@ -1536,7 +1536,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,
@@ -1545,29 +1547,24 @@
// VK_STRUCTURE_TYPE_IMPORT_PHYSICAL_ADDRESS_GOOGLE, 0,
// };
- vk_struct_common* structChain =
- structChain = vk_init_struct_chain(
- (vk_struct_common*)(&finalAllocInfo));
- structChain->pNext = nullptr;
-
- VkExportMemoryAllocateInfo* exportAllocateInfoPtr =
- (VkExportMemoryAllocateInfo*)vk_find_struct((vk_struct_common*)pAllocateInfo,
+ const VkExportMemoryAllocateInfo* exportAllocateInfoPtr =
+ vk_find_struct<VkExportMemoryAllocateInfo>(pAllocateInfo,
VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO);
- VkImportAndroidHardwareBufferInfoANDROID* importAhbInfoPtr =
- (VkImportAndroidHardwareBufferInfoANDROID*)vk_find_struct((vk_struct_common*)pAllocateInfo,
+ const VkImportAndroidHardwareBufferInfoANDROID* importAhbInfoPtr =
+ vk_find_struct<VkImportAndroidHardwareBufferInfoANDROID>(pAllocateInfo,
VK_STRUCTURE_TYPE_IMPORT_ANDROID_HARDWARE_BUFFER_INFO_ANDROID);
- VkImportMemoryBufferCollectionFUCHSIA* importBufferCollectionInfoPtr =
- (VkImportMemoryBufferCollectionFUCHSIA*)vk_find_struct((vk_struct_common*)pAllocateInfo,
+ const VkImportMemoryBufferCollectionFUCHSIA* importBufferCollectionInfoPtr =
+ vk_find_struct<VkImportMemoryBufferCollectionFUCHSIA>(pAllocateInfo,
VK_STRUCTURE_TYPE_IMPORT_MEMORY_BUFFER_COLLECTION_FUCHSIA);
- VkImportMemoryZirconHandleInfoFUCHSIA* importVmoInfoPtr =
- (VkImportMemoryZirconHandleInfoFUCHSIA*)vk_find_struct((vk_struct_common*)pAllocateInfo,
+ const VkImportMemoryZirconHandleInfoFUCHSIA* importVmoInfoPtr =
+ vk_find_struct<VkImportMemoryZirconHandleInfoFUCHSIA>(pAllocateInfo,
VK_STRUCTURE_TYPE_TEMP_IMPORT_MEMORY_ZIRCON_HANDLE_INFO_FUCHSIA);
- VkMemoryDedicatedAllocateInfo* dedicatedAllocInfoPtr =
- (VkMemoryDedicatedAllocateInfo*)vk_find_struct((vk_struct_common*)pAllocateInfo,
+ const VkMemoryDedicatedAllocateInfo* dedicatedAllocInfoPtr =
+ vk_find_struct<VkMemoryDedicatedAllocateInfo>(pAllocateInfo,
VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO);
bool shouldPassThroughDedicatedAllocInfo =
@@ -1592,12 +1589,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.
@@ -1708,8 +1701,7 @@
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;
@@ -1829,8 +1821,7 @@
if (status != ZX_OK || status2 != ZX_OK) {
ALOGE("GetColorBuffer failed: %d:%d", status, status2);
}
- structChain =
- vk_append_struct(structChain, (vk_struct_common*)(&importCbInfo));
+ vk_append_struct(&structChainIter, &importCbInfo);
}
#endif
@@ -2125,10 +2116,8 @@
transformExternalResourceMemoryRequirementsForGuest(&reqs2->memoryRequirements);
VkMemoryDedicatedRequirements* dedicatedReqs =
- (VkMemoryDedicatedRequirements*)
- vk_find_struct(
- (vk_struct_common*)reqs2,
- VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS);
+ vk_find_struct<VkMemoryDedicatedRequirements>(
+ reqs2, VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS);
if (!dedicatedReqs) return;
@@ -2157,10 +2146,8 @@
transformExternalResourceMemoryRequirementsForGuest(&reqs2->memoryRequirements);
VkMemoryDedicatedRequirements* dedicatedReqs =
- (VkMemoryDedicatedRequirements*)
- vk_find_struct(
- (vk_struct_common*)reqs2,
- VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS);
+ vk_find_struct<VkMemoryDedicatedRequirements>(
+ reqs2, VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS);
if (!dedicatedReqs) return;
@@ -2175,82 +2162,55 @@
VkImage *pImage) {
VkEncoder* enc = (VkEncoder*)context;
- 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,
+ const VkExternalMemoryImageCreateInfo* extImgCiPtr =
+ vk_find_struct<VkExternalMemoryImageCreateInfo>(
+ pCreateInfo,
VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO);
-
if (extImgCiPtr) {
- localExtImgCi = *extImgCiPtr;
+ localExtImgCi = vk_make_orphan_copy(*extImgCiPtr);
+ vk_append_struct(&structChainIter, &localExtImgCi);
}
#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
-
-#ifdef VK_USE_PLATFORM_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
+ VkNativeBufferANDROID localAnb;
+ const VkNativeBufferANDROID* anbInfoPtr =
+ vk_find_struct<VkNativeBufferANDROID>(
+ pCreateInfo,
+ VK_STRUCTURE_TYPE_NATIVE_BUFFER_ANDROID);
if (anbInfoPtr) {
- structChain =
- vk_append_struct(
- structChain, (vk_struct_common*)(&localAnb));
+ localAnb = vk_make_orphan_copy(*anbInfoPtr);
+ vk_append_struct(&structChainIter, &localAnb);
}
+ VkExternalFormatANDROID localExtFormatAndroid;
+ const VkExternalFormatANDROID* extFormatAndroidPtr =
+ vk_find_struct<VkExternalFormatANDROID>(
+ pCreateInfo,
+ VK_STRUCTURE_TYPE_EXTERNAL_FORMAT_ANDROID);
if (extFormatAndroidPtr) {
+ localExtFormatAndroid = vk_make_orphan_copy(*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 (pCreateInfo_mut->format == VK_FORMAT_UNDEFINED)
+ if (localCreateInfo.format == VK_FORMAT_UNDEFINED)
return VK_ERROR_VALIDATION_FAILED_EXT;
}
}
#endif
#ifdef VK_USE_PLATFORM_FUCHSIA
+ const VkBufferCollectionImageCreateInfoFUCHSIA* extBufferCollectionPtr =
+ vk_find_struct<VkBufferCollectionImageCreateInfoFUCHSIA>(
+ pCreateInfo,
+ VK_STRUCTURE_TYPE_BUFFER_COLLECTION_IMAGE_CREATE_INFO_FUCHSIA);
if (extBufferCollectionPtr) {
auto collection = reinterpret_cast<fuchsia::sysmem::BufferCollectionSyncPtr*>(
extBufferCollectionPtr->collection);
@@ -2273,8 +2233,8 @@
status = fuchsia_hardware_goldfish_control_DeviceCreateColorBuffer(
mControlDevice,
vmo_handle,
- pCreateInfo_mut->extent.width,
- pCreateInfo_mut->extent.height,
+ localCreateInfo.extent.width,
+ localCreateInfo.extent.height,
fuchsia_hardware_goldfish_control_FormatType_BGRA,
&status2);
if (status != ZX_OK || status2 != ZX_OK) {
@@ -2284,17 +2244,17 @@
}
// Allow external memory for all color attachments on fuchsia.
- if (pCreateInfo_mut->usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) {
+ 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;
+ 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;
@@ -2306,7 +2266,7 @@
auto& info = it->second;
info.device = device;
- info.createInfo = *pCreateInfo_mut;
+ info.createInfo = *pCreateInfo;
info.createInfo.pNext = nullptr;
if (!extImgCiPtr) return res;
@@ -2324,28 +2284,16 @@
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,
+ VK_STRUCTURE_TYPE_EXTERNAL_FORMAT_ANDROID);
if (extFormatAndroidPtr) {
if (extFormatAndroidPtr->externalFormat) {
- pCreateInfo_mut->format =
+ localCreateInfo.format =
vk_format_from_android(extFormatAndroidPtr->externalFormat);
}
}
@@ -2353,7 +2301,7 @@
VkEncoder* enc = (VkEncoder*)context;
return enc->vkCreateSamplerYcbcrConversion(
- device, pCreateInfo, pAllocator, pYcbcrConversion);
+ device, &localCreateInfo, pAllocator, pYcbcrConversion);
}
VkResult on_vkCreateSamplerYcbcrConversionKHR(
@@ -2363,34 +2311,24 @@
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,
+ 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
- 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(
@@ -2473,8 +2411,8 @@
info.createInfo = *pCreateInfo;
info.createInfo.pNext = nullptr;
- VkExternalMemoryBufferCreateInfo* extBufCi =
- (VkExternalMemoryBufferCreateInfo*)vk_find_struct((vk_struct_common*)pCreateInfo,
+ const VkExternalMemoryBufferCreateInfo* extBufCi =
+ vk_find_struct<VkExternalMemoryBufferCreateInfo>(pCreateInfo,
VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO);
if (!extBufCi) return res;
@@ -2565,9 +2503,9 @@
VkSemaphoreCreateInfo finalCreateInfo = *pCreateInfo;
- VkExportSemaphoreCreateInfoKHR* exportSemaphoreInfoPtr =
- (VkExportSemaphoreCreateInfoKHR*)vk_find_struct(
- (vk_struct_common*)pCreateInfo,
+ const VkExportSemaphoreCreateInfoKHR* exportSemaphoreInfoPtr =
+ vk_find_struct<VkExportSemaphoreCreateInfoKHR>(
+ pCreateInfo,
VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO_KHR);
#ifdef VK_USE_PLATFORM_FUCHSIA
@@ -3137,8 +3075,8 @@
(void)input_result;
VkAndroidHardwareBufferUsageANDROID* output_ahw_usage =
- (VkAndroidHardwareBufferUsageANDROID*)vk_find_struct(
- (vk_struct_common*)pImageFormatProperties,
+ vk_find_struct<VkAndroidHardwareBufferUsageANDROID>(
+ pImageFormatProperties,
VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_USAGE_ANDROID);
VkResult hostRes;
diff --git a/system/vulkan_enc/goldfish_vk_private_defs.h b/system/vulkan_enc/goldfish_vk_private_defs.h
index 3eed244..b1e5dcc 100644
--- a/system/vulkan_enc/goldfish_vk_private_defs.h
+++ b/system/vulkan_enc/goldfish_vk_private_defs.h
@@ -425,6 +425,24 @@
VkCommandBuffer commandBuffer,
VkCommandBufferResetFlags flags);
+#ifdef VK_USE_PLATFORM_FUCHSIA
+#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 VkBufferCollectionImageCreateInfoFUCHSIA {
+ VkStructureType sType;
+ const void* pNext;
+ VkBufferCollectionFUCHSIA collection;
+ uint32_t index;
+} VkBufferCollectionImageCreateInfoFUCHSIA;
+
+#define VK_STRUCTURE_TYPE_BUFFER_COLLECTION_IMAGE_CREATE_INFO_FUCHSIA \
+ ((VkStructureType)1001004005)
+#endif // VK_USE_PLATFORM_FUCHSIA
+
#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..0337f95 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:
diff --git a/system/vulkan_enc/vk_util.h b/system/vulkan_enc/vk_util.h
index da394f4..41410d3 100644
--- a/system/vulkan_enc/vk_util.h
+++ b/system/vulkan_enc/vk_util.h
@@ -33,6 +33,10 @@
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)
@@ -192,11 +196,24 @@
return NULL;
}
-#define vk_find_struct(__start, __sType) \
- __vk_find_struct((__start), __sType)
+template <class T> void vk_is_vk_struct(T *s)
+{
+ static_assert(sizeof(s->sType) == sizeof(VkStructureType), "Vulkan structures has the sType field of type VkStructureType");
+ static_assert(sizeof(s->pNext) == sizeof(void*), "Vulkan structures has the pNext field of void*");
+}
-#define vk_find_struct_const(__start, __sType) \
- (const void *)__vk_find_struct((void *)(__start), __sType)
+template <class T, class H> T* vk_find_struct(H* head, VkStructureType sType)
+{
+ vk_is_vk_struct(head);
+ return static_cast<T*>(__vk_find_struct(static_cast<void*>(head), sType));
+}
+
+template <class T, class H> const T* vk_find_struct(const H* head, VkStructureType sType)
+{
+ vk_is_vk_struct(head);
+ return static_cast<const T*>(__vk_find_struct(const_cast<void*>(static_cast<const void*>(head)),
+ sType));
+}
uint32_t vk_get_driver_version(void);
@@ -208,36 +225,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_last_struct_chain(vk_struct_common* i)
+template <class T> vk_struct_chain_iterator vk_make_chain_iterator(T* vk_struct)
{
- for (int n = 1000000; n > 0; --n) {
- vk_struct_common* next = i->pNext;
- if (next) {
- i = next;
- } else {
- return i;
- }
+ vk_is_vk_struct(vk_struct);
+ 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_is_vk_struct(vk_struct);
+
+ vk_struct_common* p = i->value;
+ if (p->pNext) {
+ ::abort();
}
- ::abort(); // crash on loops in the chain
- return NULL;
-}
+ p->pNext = reinterpret_cast<vk_struct_common *>(vk_struct);
+ vk_struct->pNext = NULL;
-static inline vk_struct_common*
-vk_append_struct(vk_struct_common* current, vk_struct_common* next)
-{
- vk_struct_common* last = vk_last_struct_chain(current);
- last->pNext = next;
- next->pNext = nullptr;
- return current;
+ *i = vk_make_chain_iterator(vk_struct);
}
#endif /* VK_UTIL_H */