Snap for 5798008 from 26ca8405fbc1e7e742fce6723f342ff975064329 to sdk-release
Change-Id: I629b1c3ea2d99e06d62c225ad4a6d93448b03563
diff --git a/shared/OpenglCodecCommon/goldfish_address_space_android.impl b/shared/OpenglCodecCommon/goldfish_address_space_android.impl
index 4926cf9..2f5e37d 100644
--- a/shared/OpenglCodecCommon/goldfish_address_space_android.impl
+++ b/shared/OpenglCodecCommon/goldfish_address_space_android.impl
@@ -228,7 +228,7 @@
const long ret = ioctl_ping(m_provider.m_fd, &request);
if (ret) {
- ALOGE("%s: ioctl_ping failed for device_type=%llu, ret=%ld",
+ ALOGE("%s: ioctl_ping failed for device_type=%d, ret=%ld",
__func__, DEVICE_TYPE_HOST_MEMORY_ALLOCATOR_ID, ret);
m_provider.close();
}
diff --git a/system/OpenglSystemCommon/HostConnection.cpp b/system/OpenglSystemCommon/HostConnection.cpp
index 5e81ead..be6a84e 100644
--- a/system/OpenglSystemCommon/HostConnection.cpp
+++ b/system/OpenglSystemCommon/HostConnection.cpp
@@ -118,6 +118,11 @@
HostConnection::~HostConnection()
{
+ // round-trip to ensure that queued commands have been processed
+ // before process pipe closure is detected.
+ if (m_rcEnc) {
+ (void) m_rcEnc->rcGetRendererVersion(m_rcEnc);
+ }
delete m_stream;
delete m_glEnc;
delete m_gl2Enc;
diff --git a/system/gralloc/gralloc.cpp b/system/gralloc/gralloc.cpp
index 39e7e16..b3d48ea 100644
--- a/system/gralloc/gralloc.cpp
+++ b/system/gralloc/gralloc.cpp
@@ -545,6 +545,12 @@
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;
+ const bool hw_render = usage & GRALLOC_USAGE_HW_RENDER;
+ const bool hw_2d = usage & GRALLOC_USAGE_HW_2D;
+ const bool hw_composer = usage & GRALLOC_USAGE_HW_COMPOSER;
+ const bool hw_fb = usage & GRALLOC_USAGE_HW_FB;
+ const bool rgb888_unsupported_usage =
+ hw_texture || hw_render || hw_2d || hw_composer || hw_fb;
#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);
@@ -608,8 +614,8 @@
glType = GL_UNSIGNED_BYTE;
break;
case HAL_PIXEL_FORMAT_RGB_888:
- if (hw_texture) {
- return -EINVAL; // we dont support RGB_888 for HW textures
+ if (rgb888_unsupported_usage) {
+ return -EINVAL; // we dont support RGB_888 for HW usage
} else {
bpp = 3;
glFormat = GL_RGB;
diff --git a/system/vulkan_enc/ResourceTracker.cpp b/system/vulkan_enc/ResourceTracker.cpp
index 2663c65..2ff4ee5 100644
--- a/system/vulkan_enc/ResourceTracker.cpp
+++ b/system/vulkan_enc/ResourceTracker.cpp
@@ -123,9 +123,8 @@
#include "android/utils/tempfile.h"
#endif
-#ifndef HAVE_MEMFD_CREATE
static inline int
-memfd_create(const char *name, unsigned int flags) {
+inline_memfd_create(const char *name, unsigned int flags) {
#ifdef HOST_BUILD
TempFile* tmpFile = tempfile_create();
return open(tempfile_path(tmpFile), O_RDWR);
@@ -134,7 +133,7 @@
return syscall(SYS_memfd_create, name, flags);
#endif
}
-#endif // !HAVE_MEMFD_CREATE
+#define memfd_create inline_memfd_create
#endif // !VK_USE_PLATFORM_ANDROID_KHR
#define RESOURCE_TRACKER_DEBUG 0
@@ -797,9 +796,6 @@
}
VkExtensionProperties anbExtProps[] = {
-#ifdef VK_USE_PLATFORM_ANDROID_KHR
- { "VK_ANDROID_native_buffer", 7 },
-#endif
#ifdef VK_USE_PLATFORM_FUCHSIA
{ "VK_KHR_external_memory_capabilities", 1},
{ "VK_KHR_external_semaphore_capabilities", 1},
@@ -810,17 +806,41 @@
filteredExts.push_back(anbExtProp);
}
- if (pPropertyCount) {
- *pPropertyCount = filteredExts.size();
- }
+ // Spec:
+ //
+ // https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/vkEnumerateInstanceExtensionProperties.html
+ //
+ // If pProperties is NULL, then the number of extensions properties
+ // available is returned in pPropertyCount. Otherwise, pPropertyCount
+ // must point to a variable set by the user to the number of elements
+ // in the pProperties array, and on return the variable is overwritten
+ // with the number of structures actually written to pProperties. If
+ // pPropertyCount is less than the number of extension properties
+ // available, at most pPropertyCount structures will be written. If
+ // pPropertyCount is smaller than the number of extensions available,
+ // VK_INCOMPLETE will be returned instead of VK_SUCCESS, to indicate
+ // that not all the available properties were returned.
+ //
+ // pPropertyCount must be a valid pointer to a uint32_t value
+ if (!pPropertyCount) return VK_ERROR_INITIALIZATION_FAILED;
- if (pPropertyCount && pProperties) {
- for (size_t i = 0; i < *pPropertyCount; ++i) {
+ if (!pProperties) {
+ *pPropertyCount = (uint32_t)filteredExts.size();
+ return VK_SUCCESS;
+ } else {
+ auto actualExtensionCount = (uint32_t)filteredExts.size();
+ auto toWrite = actualExtensionCount < *pPropertyCount ? actualExtensionCount : *pPropertyCount;
+
+ for (uint32_t i = 0; i < toWrite; ++i) {
pProperties[i] = filteredExts[i];
}
- }
- return VK_SUCCESS;
+ if (actualExtensionCount > *pPropertyCount) {
+ return VK_INCOMPLETE;
+ }
+
+ return VK_SUCCESS;
+ }
}
VkResult on_vkEnumerateDeviceExtensionProperties(
@@ -930,6 +950,9 @@
filteredExts.push_back({
"VK_ANDROID_external_memory_android_hardware_buffer", 7
});
+ filteredExts.push_back({
+ "VK_EXT_queue_family_foreign", 1
+ });
#endif
#ifdef VK_USE_PLATFORM_FUCHSIA
filteredExts.push_back({
@@ -938,18 +961,49 @@
#endif
}
- if (pPropertyCount) {
- *pPropertyCount = filteredExts.size();
- }
+ // Spec:
+ //
+ // https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/vkEnumerateDeviceExtensionProperties.html
+ //
+ // pPropertyCount is a pointer to an integer related to the number of
+ // extension properties available or queried, and is treated in the
+ // same fashion as the
+ // vkEnumerateInstanceExtensionProperties::pPropertyCount parameter.
+ //
+ // https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/vkEnumerateInstanceExtensionProperties.html
+ //
+ // If pProperties is NULL, then the number of extensions properties
+ // available is returned in pPropertyCount. Otherwise, pPropertyCount
+ // must point to a variable set by the user to the number of elements
+ // in the pProperties array, and on return the variable is overwritten
+ // with the number of structures actually written to pProperties. If
+ // pPropertyCount is less than the number of extension properties
+ // available, at most pPropertyCount structures will be written. If
+ // pPropertyCount is smaller than the number of extensions available,
+ // VK_INCOMPLETE will be returned instead of VK_SUCCESS, to indicate
+ // that not all the available properties were returned.
+ //
+ // pPropertyCount must be a valid pointer to a uint32_t value
- if (pPropertyCount && pProperties) {
- for (size_t i = 0; i < *pPropertyCount; ++i) {
+ if (!pPropertyCount) return VK_ERROR_INITIALIZATION_FAILED;
+
+ if (!pProperties) {
+ *pPropertyCount = (uint32_t)filteredExts.size();
+ return VK_SUCCESS;
+ } else {
+ auto actualExtensionCount = (uint32_t)filteredExts.size();
+ auto toWrite = actualExtensionCount < *pPropertyCount ? actualExtensionCount : *pPropertyCount;
+
+ for (uint32_t i = 0; i < toWrite; ++i) {
pProperties[i] = filteredExts[i];
}
+
+ if (actualExtensionCount > *pPropertyCount) {
+ return VK_INCOMPLETE;
+ }
+
+ return VK_SUCCESS;
}
-
-
- return VK_SUCCESS;
}
VkResult on_vkEnumeratePhysicalDevices(
@@ -965,18 +1019,26 @@
AutoLock lock(mLock);
+ // When this function is called, we actually need to do two things:
+ // - Get full information about physical devices from the host,
+ // even if the guest did not ask for it
+ // - Serve the guest query according to the spec:
+ //
+ // https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/vkEnumeratePhysicalDevices.html
+
auto it = info_VkInstance.find(instance);
if (it == info_VkInstance.end()) return VK_ERROR_INITIALIZATION_FAILED;
auto& info = it->second;
+ // Get the full host information here if it doesn't exist already.
if (info.physicalDevices.empty()) {
- uint32_t physdevCount = 0;
+ uint32_t hostPhysicalDeviceCount = 0;
lock.unlock();
VkResult countRes = enc->vkEnumeratePhysicalDevices(
- instance, &physdevCount, nullptr);
+ instance, &hostPhysicalDeviceCount, nullptr);
lock.lock();
if (countRes != VK_SUCCESS) {
@@ -985,11 +1047,11 @@
return countRes;
}
- info.physicalDevices.resize(physdevCount);
+ info.physicalDevices.resize(hostPhysicalDeviceCount);
lock.unlock();
VkResult enumRes = enc->vkEnumeratePhysicalDevices(
- instance, &physdevCount, info.physicalDevices.data());
+ instance, &hostPhysicalDeviceCount, info.physicalDevices.data());
lock.lock();
if (enumRes != VK_SUCCESS) {
@@ -999,16 +1061,41 @@
}
}
- *pPhysicalDeviceCount = (uint32_t)info.physicalDevices.size();
+ // Serve the guest query according to the spec.
+ //
+ // https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/vkEnumeratePhysicalDevices.html
+ //
+ // If pPhysicalDevices is NULL, then the number of physical devices
+ // available is returned in pPhysicalDeviceCount. Otherwise,
+ // pPhysicalDeviceCount must point to a variable set by the user to the
+ // number of elements in the pPhysicalDevices array, and on return the
+ // variable is overwritten with the number of handles actually written
+ // to pPhysicalDevices. If pPhysicalDeviceCount is less than the number
+ // of physical devices available, at most pPhysicalDeviceCount
+ // structures will be written. If pPhysicalDeviceCount is smaller than
+ // the number of physical devices available, VK_INCOMPLETE will be
+ // returned instead of VK_SUCCESS, to indicate that not all the
+ // available physical devices were returned.
- if (pPhysicalDevices && *pPhysicalDeviceCount) {
- memcpy(pPhysicalDevices,
- info.physicalDevices.data(),
- sizeof(VkPhysicalDevice) *
- info.physicalDevices.size());
+ if (!pPhysicalDevices) {
+ *pPhysicalDeviceCount = (uint32_t)info.physicalDevices.size();
+ return VK_SUCCESS;
+ } else {
+ uint32_t actualDeviceCount = (uint32_t)info.physicalDevices.size();
+ uint32_t toWrite = actualDeviceCount < *pPhysicalDeviceCount ? actualDeviceCount : *pPhysicalDeviceCount;
+
+ for (uint32_t i = 0; i < toWrite; ++i) {
+ pPhysicalDevices[i] = info.physicalDevices[i];
+ }
+
+ *pPhysicalDeviceCount = toWrite;
+
+ if (actualDeviceCount > *pPhysicalDeviceCount) {
+ return VK_INCOMPLETE;
+ }
+
+ return VK_SUCCESS;
}
-
- return VK_SUCCESS;
}
void on_vkGetPhysicalDeviceMemoryProperties(
@@ -2866,7 +2953,17 @@
if (input_result != VK_SUCCESS) return input_result;
if (!post_wait_events.empty() || !post_wait_sync_fds.empty()) {
+#ifdef VK_USE_PLATFORM_ANDROID_KHR
+ // Super bad hack: Just signal stuff early :D
+ // The reason is that it is better than freezing up.
+ // The VK CTS tests external semaphores by queueing up vkCmdWaitEvent
+ // in vkQueueSubmit, which would mean vkQueueWaitIdle here would time out.
+ //
+ // TODO (b/139194471): Have proper sync fd implementation for Android
+ // enc->vkQueueWaitIdle(queue);
+#else
enc->vkQueueWaitIdle(queue);
+#endif
}
#ifdef VK_USE_PLATFORM_FUCHSIA
@@ -2916,7 +3013,20 @@
void unwrap_vkAcquireImageANDROID_nativeFenceFd(int fd, int*) {
if (fd != -1) {
+ // Implicit Synchronization
sync_wait(fd, 3000);
+ // From libvulkan's swapchain.cpp:
+ // """
+ // NOTE: we're relying on AcquireImageANDROID to close fence_clone,
+ // even if the call fails. We could close it ourselves on failure, but
+ // that would create a race condition if the driver closes it on a
+ // failure path: some other thread might create an fd with the same
+ // number between the time the driver closes it and the time we close
+ // it. We must assume one of: the driver *always* closes it even on
+ // failure, or *never* closes it on failure.
+ // """
+ // Therefore, assume contract where we need to close fd in this driver
+ close(fd);
}
}
diff --git a/system/vulkan_enc/VkEncoder.cpp b/system/vulkan_enc/VkEncoder.cpp
index 6f43f7a..3b57678 100644
--- a/system/vulkan_enc/VkEncoder.cpp
+++ b/system/vulkan_enc/VkEncoder.cpp
@@ -7355,13 +7355,13 @@
VkCommandBuffer local_commandBuffer;
float local_blendConstants[4];
local_commandBuffer = commandBuffer;
- memcpy(&local_blendConstants, &blendConstants, 4 * sizeof(const float));
+ memcpy(local_blendConstants, blendConstants, 4 * sizeof(const float));
countingStream->rewind();
{
uint64_t cgen_var_517;
countingStream->handleMapping()->mapHandles_VkCommandBuffer_u64(&local_commandBuffer, &cgen_var_517, 1);
countingStream->write((uint64_t*)&cgen_var_517, 1 * 8);
- countingStream->write((float*)&local_blendConstants, 4 * sizeof(float));
+ countingStream->write((float*)local_blendConstants, 4 * sizeof(float));
}
uint32_t packetSize_vkCmdSetBlendConstants = 4 + 4 + (uint32_t)countingStream->bytesWritten();
countingStream->rewind();
@@ -7371,7 +7371,7 @@
uint64_t cgen_var_518;
stream->handleMapping()->mapHandles_VkCommandBuffer_u64(&local_commandBuffer, &cgen_var_518, 1);
stream->write((uint64_t*)&cgen_var_518, 1 * 8);
- stream->write((float*)&local_blendConstants, 4 * sizeof(float));
+ stream->write((float*)local_blendConstants, 4 * sizeof(float));
AEMU_SCOPED_TRACE("vkCmdSetBlendConstants readParams");
AEMU_SCOPED_TRACE("vkCmdSetBlendConstants returnUnmarshal");
mImpl->log("finish vkCmdSetBlendConstants");;