diff --git a/BUILD.gn b/BUILD.gn index 385ae8de852099fc4555701828b43c1174fdeb39..a6da1bd4f32de2ede7fd910b39a5a7bb25c7366b 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -99,16 +99,15 @@ shared_library("vulkan_goldfish") { ] deps = [ - "//zircon/public/fidl/fuchsia-hardware-goldfish:fuchsia-hardware-goldfish_c", + "//zircon/public/fidl/fuchsia-hardware-goldfish-address-space:fuchsia-hardware-goldfish-address-space_c", "//zircon/public/fidl/fuchsia-sysmem", "//zircon/public/lib/fdio", - "//zircon/public/lib/fzl", "//zircon/public/lib/trace", ] defines += [ - "QEMU_PIPE_PATH=\"/dev/sys/platform/acpi/goldfish/goldfish-pipe\"", - "GOLDFISH_ADDRESS_SPACE_DEVICE_NAME=\"/dev/sys/platform/acpi/goldfish/goldfish-pipe\"", + "QEMU_PIPE_PATH=\"/dev/class/goldfish-pipe/000\"", + "GOLDFISH_ADDRESS_SPACE_DEVICE_NAME=\"/dev/class/goldfish-address-space/000\"", ] } } diff --git a/shared/OpenglCodecCommon/goldfish_address_space.cpp b/shared/OpenglCodecCommon/goldfish_address_space.cpp index afa6b85dcf158e1b6f90614ac650333abc7d4d24..bbc59c618d539949dc5769805ab3bc9d446d9f52 100644 --- a/shared/OpenglCodecCommon/goldfish_address_space.cpp +++ b/shared/OpenglCodecCommon/goldfish_address_space.cpp @@ -127,8 +127,9 @@ void GoldfishAddressSpaceBlock::replace(GoldfishAddressSpaceBlock *other) } #elif __Fuchsia__ #include <fcntl.h> -#include <fuchsia/hardware/goldfish/c/fidl.h> -#include <lib/fzl/fdio.h> +#include <fuchsia/hardware/goldfish/address/space/c/fidl.h> +#include <lib/fdio/fdio.h> +#include <stdlib.h> #include <sys/stat.h> #include <sys/types.h> #include <unistd.h> @@ -136,22 +137,23 @@ void GoldfishAddressSpaceBlock::replace(GoldfishAddressSpaceBlock *other) #include <zircon/syscalls.h> #include <zircon/syscalls/object.h> -GoldfishAddressSpaceBlockProvider::GoldfishAddressSpaceBlockProvider() - : m_fd(::open(GOLDFISH_ADDRESS_SPACE_DEVICE_NAME, O_RDWR)) {} +GoldfishAddressSpaceBlockProvider::GoldfishAddressSpaceBlockProvider() { + fdio_get_service_handle(::open(GOLDFISH_ADDRESS_SPACE_DEVICE_NAME, O_RDWR), &m_channel); +} GoldfishAddressSpaceBlockProvider::~GoldfishAddressSpaceBlockProvider() { - ::close(m_fd); + zx_handle_close(m_channel); } GoldfishAddressSpaceBlock::GoldfishAddressSpaceBlock() : m_vmo(ZX_HANDLE_INVALID) + , m_channel(ZX_HANDLE_INVALID) , m_mmaped_ptr(NULL) , m_phys_addr(0) , m_host_addr(0) , m_offset(0) - , m_size(0) - , m_fd(-1) {} + , m_size(0) {} GoldfishAddressSpaceBlock::~GoldfishAddressSpaceBlock() { @@ -166,7 +168,7 @@ GoldfishAddressSpaceBlock &GoldfishAddressSpaceBlock::operator=(const GoldfishAd m_host_addr = rhs.m_host_addr; m_offset = rhs.m_offset; m_size = rhs.m_size; - m_fd = rhs.m_fd; + m_channel = rhs.m_channel; return *this; } @@ -182,36 +184,13 @@ bool GoldfishAddressSpaceBlock::allocate(GoldfishAddressSpaceBlockProvider *prov return false; } - { - fzl::FdioCaller caller{fbl::unique_fd(provider->m_fd)}; - - int32_t res = ZX_OK; - zx_status_t status = - fuchsia_hardware_goldfish_DeviceAllocateVmo(caller.borrow_channel(), - size, &res, &m_vmo); - if (status != ZX_OK || res != ZX_OK) { - ALOGE("%s: allocate vmo failed: %d:%d", __func__, status, res); - provider->m_fd = caller.release().release(); - return false; - } - - zx_handle_t vmo_out; - status = zx_handle_duplicate(m_vmo, ZX_DEFAULT_VMO_RIGHTS, &vmo_out); - if (status != ZX_OK) { - ALOGE("%s: vmo dup failed: %d:%d", __func__, status); - provider->m_fd = caller.release().release(); - return false; - } - - status = fuchsia_hardware_goldfish_DeviceGetPhysicalAddress( - caller.borrow_channel(), - vmo_out, &res, &m_phys_addr); - provider->m_fd = caller.release().release(); - - if (status != ZX_OK || res != ZX_OK) { - ALOGE("%s: pin vmo failed: %d:%d", __func__, status, res); - return false; - } + 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); + if (status != ZX_OK || res != ZX_OK) { + ALOGE("%s: allocate block failed: %d:%d", __func__, status, res); + return false; } m_offset = 0; @@ -221,7 +200,7 @@ bool GoldfishAddressSpaceBlock::allocate(GoldfishAddressSpaceBlockProvider *prov (unsigned long long)m_offset, (unsigned long long)m_size); - m_fd = provider->m_fd; + m_channel = provider->m_channel; return true; } @@ -284,6 +263,14 @@ void GoldfishAddressSpaceBlock::destroy() if (m_size) { 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); + if (status != ZX_OK || res != ZX_OK) { + ALOGE("%s: deallocate block failed: %d:%d", __func__, status, res); + } + m_channel = ZX_HANDLE_INVALID; m_phys_addr = 0; m_host_addr = 0; m_offset = 0; @@ -303,7 +290,7 @@ void GoldfishAddressSpaceBlock::replace(GoldfishAddressSpaceBlock *other) bool GoldfishAddressSpaceBlockProvider::is_opened() { - return m_fd >= 0; + return m_channel != ZX_HANDLE_INVALID; } #else #include <linux/types.h> diff --git a/shared/OpenglCodecCommon/goldfish_address_space.h b/shared/OpenglCodecCommon/goldfish_address_space.h index 637e20dfe38921dc5a48a1f82a4688532b1f015e..7ebb4517b5d65a66ceab03a3347b13e4750129d7 100644 --- a/shared/OpenglCodecCommon/goldfish_address_space.h +++ b/shared/OpenglCodecCommon/goldfish_address_space.h @@ -45,7 +45,11 @@ private: GoldfishAddressSpaceBlockProvider &operator=(const GoldfishAddressSpaceBlockProvider &rhs); bool is_opened(); +#ifdef __Fuchsia__ + uint32_t m_channel; +#else int m_fd; +#endif friend class GoldfishAddressSpaceBlock; }; @@ -75,13 +79,15 @@ private: #else #ifdef __Fuchsia__ uint32_t m_vmo; + uint32_t m_channel; +#else + int m_fd; #endif void *m_mmaped_ptr; uint64_t m_phys_addr; uint64_t m_host_addr; uint64_t m_offset; size_t m_size; - int m_fd; #endif }; diff --git a/system/vulkan/goldfish_vulkan.cpp b/system/vulkan/goldfish_vulkan.cpp index 3b38994d01c9b77e77015b7ddf7b075bde84c86c..4539c1b6849c506af47f1b6ed55b36762a2082d8 100644 --- a/system/vulkan/goldfish_vulkan.cpp +++ b/system/vulkan/goldfish_vulkan.cpp @@ -161,6 +161,14 @@ SetBufferCollectionConstraintsFUCHSIA(VkDevice /*device*/, AEMU_SCOPED_TRACE("vkstubhal::SetBufferCollectionConstraintsFUCHSIA"); return VK_SUCCESS; } + +VkResult +GetBufferCollectionPropertiesFUCHSIA(VkDevice /*device*/, + VkBufferCollectionFUCHSIA /*collection*/, + VkBufferCollectionPropertiesFUCHSIA* /*pProperties*/) { + AEMU_SCOPED_TRACE("vkstubhal::GetBufferCollectionPropertiesFUCHSIA"); + return VK_SUCCESS; +} #endif PFN_vkVoidFunction GetInstanceProcAddr(VkInstance instance, @@ -195,6 +203,8 @@ PFN_vkVoidFunction GetInstanceProcAddr(VkInstance instance, return reinterpret_cast<PFN_vkVoidFunction>(DestroyBufferCollectionFUCHSIA); if (strcmp(name, "vkSetBufferCollectionConstraintsFUCHSIA") == 0) return reinterpret_cast<PFN_vkVoidFunction>(SetBufferCollectionConstraintsFUCHSIA); + if (strcmp(name, "vkGetBufferCollectionPropertiesFUCHSIA") == 0) + return reinterpret_cast<PFN_vkVoidFunction>(GetBufferCollectionPropertiesFUCHSIA); #endif // Per the spec, return NULL if instance is NULL. if (!instance) @@ -440,6 +450,26 @@ VkResult SetBufferCollectionConstraintsFUCHSIA( return res; } + +VKAPI_ATTR +VkResult GetBufferCollectionPropertiesFUCHSIA( + VkDevice device, + VkBufferCollectionFUCHSIA collection, + VkBufferCollectionPropertiesFUCHSIA* pProperties) { + AEMU_SCOPED_TRACE("goldfish_vulkan::GetBufferCollectionPropertiesFUCHSIA"); + + VK_HOST_CONNECTION(VK_ERROR_DEVICE_LOST) + + if (!hostSupportsVulkan) { + return vkstubhal::GetBufferCollectionPropertiesFUCHSIA(device, collection, pProperties); + } + + VkResult res = goldfish_vk::ResourceTracker::get()-> + on_vkGetBufferCollectionPropertiesFUCHSIA( + vkEnc, VK_SUCCESS, device, collection, pProperties); + + return res; +} #endif static PFN_vkVoidFunction GetDeviceProcAddr(VkDevice device, const char* name) { @@ -473,6 +503,9 @@ static PFN_vkVoidFunction GetDeviceProcAddr(VkDevice device, const char* name) { if (!strcmp(name, "vkSetBufferCollectionConstraintsFUCHSIA")) { return (PFN_vkVoidFunction)SetBufferCollectionConstraintsFUCHSIA; } + if (!strcmp(name, "vkGetBufferCollectionPropertiesFUCHSIA")) { + return (PFN_vkVoidFunction)GetBufferCollectionPropertiesFUCHSIA; + } #endif if (!strcmp(name, "vkGetDeviceProcAddr")) { return (PFN_vkVoidFunction)(GetDeviceProcAddr); diff --git a/system/vulkan_enc/ResourceTracker.cpp b/system/vulkan_enc/ResourceTracker.cpp index 01ad42b77cd9831a324bef06c3733eedf81ed255..36c2a6b9a03f54de863323b264f2aa4b7ed7fcfb 100644 --- a/system/vulkan_enc/ResourceTracker.cpp +++ b/system/vulkan_enc/ResourceTracker.cpp @@ -58,7 +58,6 @@ typedef struct VkImportMemoryBufferCollectionFUCHSIA { #ifdef VK_USE_PLATFORM_FUCHSIA #include <cutils/native_handle.h> -#include <fuchsia/hardware/goldfish/c/fidl.h> #include <fuchsia/sysmem/cpp/fidl.h> #include <lib/fdio/directory.h> #include <lib/fdio/fd.h> @@ -1210,7 +1209,7 @@ public: for (uint32_t i = 0; i < info.memProps.memoryTypeCount; ++i) { if (info.memProps.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) { - pProperties->memoryTypeBits = 1ull << i; + pProperties->memoryTypeBits |= 1ull << i; } } return VK_SUCCESS; @@ -1364,6 +1363,45 @@ public: (*sysmem_collection)->SetConstraints(true, constraints); return VK_SUCCESS; } + + VkResult on_vkGetBufferCollectionPropertiesFUCHSIA( + void*, VkResult, + VkDevice device, + VkBufferCollectionFUCHSIA collection, + VkBufferCollectionPropertiesFUCHSIA* pProperties) { + auto sysmem_collection = reinterpret_cast<fuchsia::sysmem::BufferCollectionSyncPtr*>(collection); + fuchsia::sysmem::BufferCollectionInfo_2 info; + zx_status_t status2; + zx_status_t status = (*sysmem_collection)->WaitForBuffersAllocated(&status2, &info); + if (status != ZX_OK || status2 != ZX_OK) { + ALOGE("Failed wait for allocation: %d %d", status, status2); + return VK_ERROR_INITIALIZATION_FAILED; + } + if (!info.settings.has_image_format_constraints) { + return VK_ERROR_INITIALIZATION_FAILED; + } + pProperties->count = info.buffer_count; + + AutoLock lock(mLock); + + auto deviceIt = info_VkDevice.find(device); + + if (deviceIt == info_VkDevice.end()) { + return VK_ERROR_INITIALIZATION_FAILED; + } + + auto& deviceInfo = deviceIt->second; + + // Device local memory type supported. + pProperties->memoryTypeBits = 0; + for (uint32_t i = 0; i < deviceInfo.memProps.memoryTypeCount; ++i) { + if (deviceInfo.memProps.memoryTypes[i].propertyFlags & + VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) { + pProperties->memoryTypeBits |= 1ull << i; + } + } + return VK_SUCCESS; + } #endif HostMemBlockIndex getOrAllocateHostMemBlockLocked( @@ -1698,10 +1736,17 @@ public: } if (vmo_handle != ZX_HANDLE_INVALID) { - uint64_t cb = 0; + uint32_t cb = 0; #ifdef VK_USE_PLATFORM_FUCHSIA - zx_object_get_cookie(vmo_handle, vmo_handle, &cb); + // 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 (cb) { @@ -2377,11 +2422,12 @@ public: abort(); } } - status = zx_object_set_cookie(memoryInfo.vmoHandle, - memoryInfo.vmoHandle, - imageInfo.cbHandle); + // 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 to set color buffer cookie", __func__); + ALOGE("%s: failed writing color buffer id to vmo", __func__); abort(); } // Color buffer backed images are already bound. @@ -3692,6 +3738,15 @@ VkResult ResourceTracker::on_vkSetBufferCollectionConstraintsFUCHSIA( return mImpl->on_vkSetBufferCollectionConstraintsFUCHSIA( context, input_result, device, collection, pImageInfo); } + +VkResult ResourceTracker::on_vkGetBufferCollectionPropertiesFUCHSIA( + void* context, VkResult input_result, + VkDevice device, + VkBufferCollectionFUCHSIA collection, + VkBufferCollectionPropertiesFUCHSIA* pProperties) { + return mImpl->on_vkGetBufferCollectionPropertiesFUCHSIA( + context, input_result, device, collection, pProperties); +} #endif VkResult ResourceTracker::on_vkGetAndroidHardwareBufferPropertiesANDROID( diff --git a/system/vulkan_enc/ResourceTracker.h b/system/vulkan_enc/ResourceTracker.h index 200bfb6870dcb756d280eff4dfd080173ff822c8..e3189e4d6f0424d4ea9e4f4ff3ff04a45b9f8908 100644 --- a/system/vulkan_enc/ResourceTracker.h +++ b/system/vulkan_enc/ResourceTracker.h @@ -249,6 +249,11 @@ public: VkDevice device, VkBufferCollectionFUCHSIA collection, const VkImageCreateInfo* pImageInfo); + VkResult on_vkGetBufferCollectionPropertiesFUCHSIA( + void* context, VkResult input_result, + VkDevice device, + VkBufferCollectionFUCHSIA collection, + VkBufferCollectionPropertiesFUCHSIA* pProperties); #endif VkResult on_vkGetAndroidHardwareBufferPropertiesANDROID(