diff --git a/BUILD.gn b/BUILD.gn index 1f50018866ae99cddb52da32b177aa238d71ff17..348ab87c46af21a98e704da82ad1a25b67b92f33 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -87,7 +87,11 @@ shared_library("vulkan_goldfish") { 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 @@ shared_library("vulkan_goldfish") { 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 0884d5740eff21f5a633ee305df52e6f3efe0ad6..8d64ab8419aa90c7845b9cfefe7342add9715ca7 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 @@ private: 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 0000000000000000000000000000000000000000..f4ee61c5e332b1fc04e4e342560ecaa707c802ed --- /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 05f14f1f3a3f9246592492a7dd94cd8c73c7f0d1..516791bd60e9c0c9ecdd1cb1a344bc2fb0e5abc2 100644 --- a/system/vulkan_enc/AndroidHardwareBuffer.cpp +++ b/system/vulkan_enc/AndroidHardwareBuffer.cpp @@ -59,8 +59,8 @@ VkResult getAndroidHardwareBufferPropertiesANDROID( 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 @@ VkResult getAndroidHardwareBufferPropertiesANDROID( 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 631f24d1a1cceeed1420f6e1adf620e5cb88b9cc..3b5bdb85f79c486d85d43e4e635013bd598fa6e8 100644 --- a/system/vulkan_enc/ResourceTracker.cpp +++ b/system/vulkan_enc/ResourceTracker.cpp @@ -1536,7 +1536,9 @@ public: 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 @@ public: // 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 @@ public: 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 @@ public: 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 @@ public: 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 @@ public: 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 @@ public: 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 @@ public: 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; - } - -#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)); + 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, + 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 @@ public: 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 @@ public: } // 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 @@ public: 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 @@ public: const VkAllocationCallbacks* pAllocator, VkSamplerYcbcrConversion* pYcbcrConversion) { - VkSamplerYcbcrConversionCreateInfo localCreateInfo = *pCreateInfo; - VkSamplerYcbcrConversionCreateInfo* pCreateInfo_mut = &localCreateInfo; - -#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); + VkSamplerYcbcrConversionCreateInfo localCreateInfo = vk_make_orphan_copy(*pCreateInfo); #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 @@ public: VkEncoder* enc = (VkEncoder*)context; return enc->vkCreateSamplerYcbcrConversion( - device, pCreateInfo, pAllocator, pYcbcrConversion); + device, &localCreateInfo, pAllocator, pYcbcrConversion); } VkResult on_vkCreateSamplerYcbcrConversionKHR( @@ -2363,34 +2311,24 @@ public: 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 @@ public: 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 @@ public: 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 @@ public: (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 3eed2442ed3805998e3dc53e7c1f42bfce6a99bd..b1e5dcc29eb48c0020d9cf11879f15f5b4125cf4 100644 --- a/system/vulkan_enc/goldfish_vk_private_defs.h +++ b/system/vulkan_enc/goldfish_vk_private_defs.h @@ -425,6 +425,24 @@ typedef void (VKAPI_PTR *PFN_vkResetCommandBufferAsyncGOOGLE)( 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 3bac828aab8089d82e9bd112d96a5f0225921991..0337f95a088b79428bab3bda9a31173b9eb9e009 100644 --- a/system/vulkan_enc/vk_format_info.h +++ b/system/vulkan_enc/vk_format_info.h @@ -58,7 +58,7 @@ vk_format_from_android(unsigned android_format) } 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 da394f4ebfc4271b2be790c1c7d1cb89fc05e2c6..41410d34f4c46c98b1f2781517760c68b9507ee7 100644 --- a/system/vulkan_enc/vk_util.h +++ b/system/vulkan_enc/vk_util.h @@ -33,6 +33,10 @@ struct vk_struct_common { 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 @@ __vk_find_struct(void *start, VkStructureType sType) 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*"); +} + +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)); +} -#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, 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 @@ uint32_t vk_get_version_override(void); #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) +template <class T> T vk_make_orphan_copy(const T& vk_struct) { + T copy = vk_struct; + copy.pNext = NULL; + return copy; +} + +template <class T> vk_struct_chain_iterator vk_make_chain_iterator(T* vk_struct) { - start->pNext = nullptr; - return start; + vk_is_vk_struct(vk_struct); + vk_struct_chain_iterator result = { reinterpret_cast<vk_struct_common*>(vk_struct) }; + return result; } -static inline vk_struct_common* -vk_last_struct_chain(vk_struct_common* i) +template <class T> void vk_append_struct(vk_struct_chain_iterator* i, 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_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 */