Merge "reland: virtio-gpu-asg transport"
diff --git a/shared/GoldfishAddressSpace/Android.bp b/shared/GoldfishAddressSpace/Android.bp
index 6dcdb56..4e8d31d 100644
--- a/shared/GoldfishAddressSpace/Android.bp
+++ b/shared/GoldfishAddressSpace/Android.bp
@@ -6,11 +6,13 @@
],
shared_libs: [
"liblog",
+ "libdrm",
],
export_include_dirs: [
"include",
],
cflags: [
"-DLOG_TAG=\"goldfish-address-space\"",
+ "-DVIRTIO_GPU",
],
}
diff --git a/shared/GoldfishAddressSpace/include/goldfish_address_space.h b/shared/GoldfishAddressSpace/include/goldfish_address_space.h
index 044e18a..ad5e3cb 100644
--- a/shared/GoldfishAddressSpace/include/goldfish_address_space.h
+++ b/shared/GoldfishAddressSpace/include/goldfish_address_space.h
@@ -49,6 +49,7 @@
Media = 1,
HostMemoryAllocator = 5,
SharedSlotsHostMemoryAllocator = 6,
+ VirtioGpuGraphics = 10,
};
class GoldfishAddressSpaceBlockProvider {
@@ -135,7 +136,7 @@
// require different lifetime expectations versus GoldfishAddressSpaceBlock).
// We also expose the ping info struct that is shared between host and guest.
-struct goldfish_address_space_ping {
+struct address_space_ping {
uint64_t offset;
uint64_t size;
uint64_t metadata;
@@ -164,6 +165,97 @@
void goldfish_address_space_unmap(void* ptr, uint64_t size);
bool goldfish_address_space_set_subdevice_type(address_space_handle_t, GoldfishAddressSpaceSubdeviceType type, address_space_handle_t*);
-bool goldfish_address_space_ping(address_space_handle_t, struct goldfish_address_space_ping*);
+bool goldfish_address_space_ping(address_space_handle_t, struct address_space_ping*);
+
+// virtio-gpu version
+
+struct address_space_virtgpu_hostmem_info {
+ uint32_t id;
+ uint32_t bo;
+ void* ptr;
+};
+
+struct address_space_virtgpu_info {
+ int fd;
+ uint32_t resp_bo;
+ uint32_t resp_resid;
+ void* resp_mapped_ptr;
+};
+
+address_space_handle_t virtgpu_address_space_open();
+void virtgpu_address_space_close(address_space_handle_t);
+
+// Ping with no response
+bool virtgpu_address_space_ping(address_space_handle_t, struct address_space_ping*);
+
+bool virtgpu_address_space_create_context_with_subdevice(
+ address_space_handle_t,
+ uint32_t subdevice_type,
+ struct address_space_virtgpu_info* info_out);
+
+bool virtgpu_address_space_allocate_hostmem(
+ address_space_handle_t fd,
+ size_t size,
+ uint64_t hostmem_id,
+ struct address_space_virtgpu_hostmem_info* hostmem_info_out);
+
+// Ping with response
+bool virtgpu_address_space_ping_with_response(
+ struct address_space_virtgpu_info* info,
+ struct address_space_ping* ping);
+
+// typedef/struct to abstract over goldfish vs virtio-gpu implementations
+typedef address_space_handle_t (*address_space_open_t)(void);
+typedef void (*address_space_close_t)(address_space_handle_t);
+
+typedef bool (*address_space_allocate_t)(
+ address_space_handle_t, size_t size, uint64_t* phys_addr, uint64_t* offset);
+typedef bool (*address_space_free_t)(
+ address_space_handle_t, uint64_t offset);
+
+typedef bool (*address_space_claim_shared_t)(
+ address_space_handle_t, uint64_t offset, uint64_t size);
+typedef bool (*address_space_unclaim_shared_t)(
+ address_space_handle_t, uint64_t offset);
+
+// pgoff is the offset into the page to return in the result
+typedef void* (*address_space_map_t)(
+ address_space_handle_t, uint64_t offset, uint64_t size, uint64_t pgoff);
+typedef void (*address_space_unmap_t)(void* ptr, uint64_t size);
+
+typedef bool (*address_space_set_subdevice_type_t)(
+ address_space_handle_t, GoldfishAddressSpaceSubdeviceType type, address_space_handle_t*);
+typedef bool (*address_space_ping_t)(
+ address_space_handle_t, struct address_space_ping*);
+
+// Specific to virtio-gpu
+typedef bool (*address_space_create_context_with_subdevice_t)(
+ address_space_handle_t,
+ uint32_t subdevice_type,
+ struct address_space_virtgpu_info* info_out);
+
+typedef bool (*address_space_allocate_hostmem_t)(
+ address_space_handle_t fd,
+ size_t size,
+ uint64_t hostmem_id,
+ struct address_space_virtgpu_hostmem_info* hostmem_info_out);
+
+typedef bool (*address_space_ping_with_response_t)(
+ struct address_space_virtgpu_info* info,
+ struct address_space_ping* ping);
+
+struct address_space_ops {
+ address_space_open_t open;
+ address_space_close_t close;
+ address_space_claim_shared_t claim_shared;
+ address_space_unclaim_shared_t unclaim_shared;
+ address_space_map_t map;
+ address_space_unmap_t unmap;
+ address_space_set_subdevice_type_t set_subdevice_type;
+ address_space_ping_t ping;
+ address_space_create_context_with_subdevice_t create_context_with_subdevice;
+ address_space_allocate_hostmem_t allocate_hostmem;
+ address_space_ping_with_response_t ping_with_response;
+};
#endif // #ifndef ANDROID_INCLUDE_HARDWARE_GOLDFISH_ADDRESS_SPACE_H
diff --git a/shared/GoldfishAddressSpace/include/goldfish_address_space_android.impl b/shared/GoldfishAddressSpace/include/goldfish_address_space_android.impl
index 8ff7e78..a8a70af 100644
--- a/shared/GoldfishAddressSpace/include/goldfish_address_space_android.impl
+++ b/shared/GoldfishAddressSpace/include/goldfish_address_space_android.impl
@@ -25,9 +25,15 @@
#include <errno.h>
#include <memory>
+#ifdef VIRTIO_GPU
+#include <drm/virtgpu_drm.h>
+#include <xf86drm.h>
+#endif
+
#include <log/log.h>
#include "goldfish_address_space.h"
+#include "virtio_gpu_next.h"
namespace {
@@ -46,7 +52,7 @@
#define GOLDFISH_ADDRESS_SPACE_IOCTL_OP(OP, T) _IOWR(GOLDFISH_ADDRESS_SPACE_IOCTL_MAGIC, OP, T)
#define GOLDFISH_ADDRESS_SPACE_IOCTL_ALLOCATE_BLOCK GOLDFISH_ADDRESS_SPACE_IOCTL_OP(10, struct goldfish_address_space_allocate_block)
#define GOLDFISH_ADDRESS_SPACE_IOCTL_DEALLOCATE_BLOCK GOLDFISH_ADDRESS_SPACE_IOCTL_OP(11, __u64)
-#define GOLDFISH_ADDRESS_SPACE_IOCTL_PING GOLDFISH_ADDRESS_SPACE_IOCTL_OP(12, struct goldfish_address_space_ping)
+#define GOLDFISH_ADDRESS_SPACE_IOCTL_PING GOLDFISH_ADDRESS_SPACE_IOCTL_OP(12, struct address_space_ping)
#define GOLDFISH_ADDRESS_SPACE_IOCTL_CLAIM_SHARED GOLDFISH_ADDRESS_SPACE_IOCTL_OP(13, struct goldfish_address_space_claim_shared)
#define GOLDFISH_ADDRESS_SPACE_IOCTL_UNCLAIM_SHARED GOLDFISH_ADDRESS_SPACE_IOCTL_OP(14, __u64)
@@ -70,14 +76,14 @@
return ::ioctl(fd, GOLDFISH_ADDRESS_SPACE_IOCTL_DEALLOCATE_BLOCK, &offset);
}
-long ioctl_ping(int fd, struct goldfish_address_space_ping *request)
+long ioctl_ping(int fd, struct address_space_ping *request)
{
return ::ioctl(fd, GOLDFISH_ADDRESS_SPACE_IOCTL_PING, request);
}
long set_address_space_subdevice_type(int fd, uint64_t type)
{
- struct goldfish_address_space_ping request;
+ struct address_space_ping request;
::memset(&request, 0, sizeof(request));
request.version = sizeof(request);
request.metadata = type;
@@ -359,7 +365,7 @@
return -ENODEV;
}
- struct goldfish_address_space_ping request;
+ struct address_space_ping request;
if (m_useSharedSlots) {
// shared memory slots are supported
::memset(&request, 0, sizeof(request));
@@ -415,7 +421,7 @@
}
if (block->guestPtr()) {
- struct goldfish_address_space_ping request;
+ struct address_space_ping request;
::memset(&request, 0, sizeof(request));
request.version = sizeof(request);
request.offset = block->offset();
@@ -517,7 +523,7 @@
bool goldfish_address_space_set_subdevice_type(
address_space_handle_t handle, GoldfishAddressSpaceSubdeviceType type,
address_space_handle_t* handle_out) {
- struct goldfish_address_space_ping request;
+ struct address_space_ping request;
request.metadata = (uint64_t)type;
*handle_out = handle;
return goldfish_address_space_ping(handle, &request);
@@ -525,7 +531,7 @@
bool goldfish_address_space_ping(
address_space_handle_t handle,
- struct goldfish_address_space_ping* ping) {
+ struct address_space_ping* ping) {
long res = ioctl_ping(handle, ping);
if (res) {
@@ -535,3 +541,240 @@
return true;
}
+
+// virtio-gpu version
+address_space_handle_t virtgpu_address_space_open() {
+return drmOpenRender(128);
+}
+
+void virtgpu_address_space_close(address_space_handle_t fd) {
+close(fd);
+}
+
+// kVirtioGpuAddressSpaceContextCreateWithSubdevice | subdeviceType
+const uint32_t kVirtioGpuAddressSpaceContextCreateWithSubdevice = 0x1001;
+
+// kVirtioGpuAddressSpacePing | offset_lo | offset_hi | size_lo | size_hi | metadata_lo | metadata_hi | version | wait_fd | wait_flags | direction
+// no output
+const uint32_t kVirtioGpuAddressSpacePing = 0x1002;
+
+// kVirtioGpuAddressSpacePingWithResponse | resp_resid | offset_lo | offset_hi | metadata_lo | metadata_hi | version | wait_fd | wait_flags | direction
+// out: same as input then | out: error
+const uint32_t kVirtioGpuAddressSpacePingWithResponse = 0x1003;
+
+// Ping with no response
+bool virtgpu_address_space_ping(address_space_handle_t fd, struct address_space_ping* info) {
+
+ uint32_t words[] = {
+ kVirtioGpuAddressSpacePing,
+ (uint32_t)(info->offset), (uint32_t)(info->offset >> 32),
+ (uint32_t)(info->size), (uint32_t)(info->size >> 32),
+ (uint32_t)(info->metadata), (uint32_t)(info->metadata >> 32),
+ (uint32_t)(info->version), (uint32_t)(info->wait_fd),
+ (uint32_t)(info->wait_flags), (uint32_t)(info->direction),
+ };
+
+ drm_virtgpu_execbuffer execbuffer = {
+ .flags = 0,
+ .size = sizeof(words),
+ .command = (uint64_t)(uintptr_t)(words),
+ .bo_handles = 0,
+ .num_bo_handles = 0,
+ .fence_fd = -1,
+ };
+
+ int queue_work_err = drmIoctl(fd, DRM_IOCTL_VIRTGPU_EXECBUFFER, &execbuffer);
+
+ if (queue_work_err) {
+ ALOGE("%s: failed with %d executing command buffer (%s)\n", __func__,
+ queue_work_err, strerror(errno));
+ return false;
+ }
+
+ return true;
+}
+
+bool virtgpu_address_space_create_context_with_subdevice(
+ address_space_handle_t fd,
+ uint32_t subdevice_type,
+ struct address_space_virtgpu_info* info_out) {
+
+ // response page
+ drm_virtgpu_resource_create create = {
+ .target = PIPE_BUFFER,
+ .format = VIRGL_FORMAT_R8_UNORM,
+ .bind = VIRGL_BIND_CUSTOM,
+ .width = 4096,
+ .height = 1U,
+ .depth = 1U,
+ .array_size = 0U,
+ .size = 4096,
+ .stride = 4096,
+ };
+
+ int ret = drmIoctl(fd, DRM_IOCTL_VIRTGPU_RESOURCE_CREATE, &create);
+ if (ret) {
+ ALOGE("%s: failed with %d allocating command buffer (%s)\n",
+ __func__, ret, strerror(errno));
+ return false;
+ }
+
+ drm_virtgpu_map map = {
+ .handle = create.bo_handle,
+ };
+
+ ret = drmIoctl(fd, DRM_IOCTL_VIRTGPU_MAP, &map);
+ if (ret) {
+ ALOGE("%s: failed with %d mapping command response buffer (%s)\n",
+ __func__, ret, strerror(errno));
+ return false;
+ }
+
+ void* ptr = static_cast<unsigned char*>(
+ mmap64(nullptr, 4096, PROT_WRITE, MAP_SHARED, fd, map.offset));
+
+ if (ptr == MAP_FAILED) {
+ ALOGE("%s: failed with %d mmap'ing command response buffer (%s)\n",
+ __func__, errno, strerror(errno));
+ return false;
+ }
+
+ info_out->fd = fd;
+ info_out->resp_bo = create.bo_handle;
+ info_out->resp_resid = create.res_handle;
+ info_out->resp_mapped_ptr = ptr;
+
+ ALOGD("%s: resp bo: %u resid %u mapped %p\n", __func__,
+ create.bo_handle, create.res_handle, ptr);
+
+ // Context creation command
+ uint32_t words[] = {
+ kVirtioGpuAddressSpaceContextCreateWithSubdevice,
+ subdevice_type,
+ };
+
+ drm_virtgpu_execbuffer execbuffer = {
+ .flags = 0,
+ .size = sizeof(words),
+ .command = (uint64_t)(uintptr_t)(words),
+ .bo_handles = 0,
+ .num_bo_handles = 0,
+ .fence_fd = -1,
+ };
+
+ int queue_work_err = drmIoctl(fd, DRM_IOCTL_VIRTGPU_EXECBUFFER, &execbuffer);
+
+ if (queue_work_err) {
+ ALOGE("%s: failed with %d executing command buffer (%s)\n", __func__,
+ queue_work_err, strerror(errno));
+ return false;
+ }
+
+ return true;
+}
+
+bool virtgpu_address_space_allocate_hostmem(
+ address_space_handle_t fd,
+ size_t size,
+ uint64_t hostmem_id,
+ struct address_space_virtgpu_hostmem_info* hostmem_info_out) {
+
+ struct drm_virtgpu_resource_create_blob drm_rc_blob = { 0 };
+ drm_rc_blob.blob_mem = VIRTGPU_BLOB_MEM_HOST;
+ drm_rc_blob.blob_flags = VIRTGPU_BLOB_FLAG_MAPPABLE;
+ drm_rc_blob.blob_id = hostmem_id;
+ drm_rc_blob.size = size;
+
+ int res = drmIoctl(
+ fd, DRM_IOCTL_VIRTGPU_RESOURCE_CREATE_BLOB, &drm_rc_blob);
+
+ if (res) {
+ ALOGE("%s: Failed to resource create v2: sterror: %s errno: %d\n", __func__,
+ strerror(errno), errno);
+ abort();
+ }
+
+ struct drm_virtgpu_map map_info = {
+ .handle = drm_rc_blob.bo_handle,
+ };
+
+ res = drmIoctl(fd, DRM_IOCTL_VIRTGPU_MAP, &map_info);
+ if (res) {
+ ALOGE("%s: Failed to virtgpu map: sterror: %s errno: %d\n", __func__,
+ strerror(errno), errno);
+ abort();
+ }
+
+ void* directMappedAddr = mmap64(0, size, PROT_WRITE, MAP_SHARED, fd, map_info.offset);
+
+ if (!directMappedAddr) {
+ ALOGE("%s: mmap of virtio gpu resource failed\n", __func__);
+ abort();
+ }
+
+ hostmem_info_out->id = hostmem_id;
+ hostmem_info_out->bo = drm_rc_blob.bo_handle;
+ hostmem_info_out->ptr = directMappedAddr;
+ return true;
+}
+
+uint64_t buildu64(uint32_t lo, uint32_t hi) {
+ uint64_t res = (uint64_t)lo;
+ uint64_t hi64 = (uint64_t)hi;
+ return res | (hi64 << 32);
+}
+
+// Ping with response
+bool virtgpu_address_space_ping_with_response(
+ struct address_space_virtgpu_info* info,
+ struct address_space_ping* ping) {
+
+ uint32_t words[] = {
+ kVirtioGpuAddressSpacePingWithResponse,
+ info->resp_resid,
+ (uint32_t)(ping->offset), (uint32_t)(ping->offset >> 32),
+ (uint32_t)(ping->size), (uint32_t)(ping->size >> 32),
+ (uint32_t)(ping->metadata), (uint32_t)(ping->metadata >> 32),
+ (uint32_t)(ping->version), (uint32_t)(ping->wait_fd),
+ (uint32_t)(ping->wait_flags), (uint32_t)(ping->direction),
+ };
+
+ drm_virtgpu_execbuffer execbuffer = {
+ .flags = 0,
+ .size = sizeof(words),
+ .command = (uint64_t)(uintptr_t)(words),
+ .bo_handles = (uint64_t)(uintptr_t)(&info->resp_bo),
+ .num_bo_handles = 1,
+ .fence_fd = -1,
+ };
+
+ int queue_work_err = drmIoctl(info->fd, DRM_IOCTL_VIRTGPU_EXECBUFFER, &execbuffer);
+
+ if (queue_work_err) {
+ ALOGE("%s: failed with %d executing command buffer (%s)\n", __func__,
+ queue_work_err, strerror(errno));
+ return false;
+ }
+
+ struct drm_virtgpu_3d_wait waitcmd;
+ memset(&waitcmd, 0, sizeof(waitcmd));
+ waitcmd.handle = info->resp_bo;
+
+ int ret = drmIoctl(info->fd, DRM_IOCTL_VIRTGPU_WAIT, &waitcmd);
+ if (ret) {
+ ALOGE("%s: DRM_IOCTL_VIRTGPU_WAIT failed with %d (%s)\n", __func__, errno, strerror(errno));
+ return false;
+ }
+
+ uint32_t* respWords = (uint32_t*)info->resp_mapped_ptr;
+
+ ping->offset = buildu64(respWords[0], respWords[1]);
+ ping->size = buildu64(respWords[2], respWords[3]);
+ ping->metadata = buildu64(respWords[4], respWords[5]);
+ ping->version = respWords[6];
+ ping->wait_fd = respWords[7];
+ ping->wait_flags = respWords[8];
+ ping->direction = respWords[9];
+
+ return true;
+}
diff --git a/shared/GoldfishAddressSpace/include/goldfish_address_space_host.impl b/shared/GoldfishAddressSpace/include/goldfish_address_space_host.impl
index 8995c6b..d1fa4a3 100644
--- a/shared/GoldfishAddressSpace/include/goldfish_address_space_host.impl
+++ b/shared/GoldfishAddressSpace/include/goldfish_address_space_host.impl
@@ -377,7 +377,7 @@
bool goldfish_address_space_set_subdevice_type(
address_space_handle_t handle, GoldfishAddressSpaceSubdeviceType type,
address_space_handle_t* handle_out) {
- struct goldfish_address_space_ping request;
+ struct address_space_ping request;
request.metadata = (uint64_t)type;
*handle_out = handle;
return goldfish_address_space_ping(handle, &request);
@@ -385,7 +385,7 @@
bool goldfish_address_space_ping(
address_space_handle_t handle,
- struct goldfish_address_space_ping* ping) {
+ struct address_space_ping* ping) {
AddressSpaceDevicePingInfo* asHostPingInfo =
reinterpret_cast<AddressSpaceDevicePingInfo*>(ping);
diff --git a/shared/GoldfishAddressSpace/include/virtio_gpu_next.h b/shared/GoldfishAddressSpace/include/virtio_gpu_next.h
new file mode 100644
index 0000000..610dc51
--- /dev/null
+++ b/shared/GoldfishAddressSpace/include/virtio_gpu_next.h
@@ -0,0 +1,58 @@
+// Copyright (C) 2020 The Android Open Source Project
+// Copyright (C) 2020 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
+
+#ifndef HOST_BUILD
+#include "drm.h"
+#endif
+
+#define PIPE_BUFFER 0
+#define VIRGL_FORMAT_R8_UNORM 64
+#define VIRGL_BIND_CUSTOM (1 << 17)
+
+#define DRM_VIRTGPU_RESOURCE_CREATE_BLOB 0x0a
+
+#define VIRTGPU_PARAM_RESOURCE_BLOB 3 /* DRM_VIRTGPU_RESOURCE_CREATE_BLOB */
+#define VIRTGPU_PARAM_HOST_VISIBLE 4
+
+struct drm_virtgpu_resource_create_blob {
+#define VIRTGPU_BLOB_MEM_GUEST 0x0001
+#define VIRTGPU_BLOB_MEM_HOST 0x0002
+#define VIRTGPU_BLOB_MEM_HOST_GUEST 0x0003
+
+#define VIRTGPU_BLOB_FLAG_MAPPABLE 0x0001
+#define VIRTGPU_BLOB_FLAG_SHAREABLE 0x0002
+#define VIRTGPU_BLOB_FLAG_CROSS_DEVICE 0x0004
+ /* zero is invalid blob_mem */
+ uint32_t blob_mem;
+ uint32_t blob_flags;
+ uint32_t bo_handle;
+ uint32_t res_handle;
+ uint64_t size;
+
+ /*
+ * for 3D contexts with VIRTGPU_BLOB_MEM_HOSTGUEST and
+ * VIRTGPU_BLOB_MEM_HOST otherwise, must be zero.
+ */
+ uint32_t pad;
+ uint32_t cmd_size;
+ uint64_t cmd;
+ uint64_t blob_id;
+};
+
+
+#define DRM_IOCTL_VIRTGPU_RESOURCE_CREATE_BLOB \
+ DRM_IOWR(DRM_COMMAND_BASE + DRM_VIRTGPU_RESOURCE_CREATE_BLOB, \
+ struct drm_virtgpu_resource_create_blob)
diff --git a/system/OpenglSystemCommon/AddressSpaceStream.cpp b/system/OpenglSystemCommon/AddressSpaceStream.cpp
index 3f066f3..df34adc 100644
--- a/system/OpenglSystemCommon/AddressSpaceStream.cpp
+++ b/system/OpenglSystemCommon/AddressSpaceStream.cpp
@@ -42,7 +42,7 @@
return nullptr;
}
- struct goldfish_address_space_ping request;
+ struct address_space_ping request;
request.metadata = ASG_GET_RING;
if (!goldfish_address_space_ping(child_device_handle, &request)) {
ALOGE("AddressSpaceStream::create failed (get ring)\n");
@@ -123,21 +123,156 @@
context.ring_config->host_consumed_pos = 0;
context.ring_config->guest_write_pos = 0;
+ struct address_space_ops ops = {
+ .open = goldfish_address_space_open,
+ .close = goldfish_address_space_close,
+ .claim_shared = goldfish_address_space_claim_shared,
+ .unclaim_shared = goldfish_address_space_unclaim_shared,
+ .map = goldfish_address_space_map,
+ .unmap = goldfish_address_space_unmap,
+ .set_subdevice_type = goldfish_address_space_set_subdevice_type,
+ .ping = goldfish_address_space_ping,
+ };
+
AddressSpaceStream* res =
new AddressSpaceStream(
child_device_handle, version, context,
- ringOffset, bufferOffset);
+ ringOffset, bufferOffset, false /* not virtio */, ops);
return res;
}
+#ifdef HOST_BUILD
+AddressSpaceStream* createVirtioGpuAddressSpaceStream(size_t ignored_bufSize) {
+ // Ignore incoming ignored_bufSize
+ (void)ignored_bufSize;
+ return nullptr;
+}
+#else
+AddressSpaceStream* createVirtioGpuAddressSpaceStream(size_t ignored_bufSize) {
+ // Ignore incoming ignored_bufSize
+ (void)ignored_bufSize;
+
+ auto handle = virtgpu_address_space_open();
+
+ if (handle <= 0) {
+ ALOGE("AddressSpaceStream::create failed (open device)\n");
+ return nullptr;
+ }
+
+ struct address_space_virtgpu_info virtgpu_info;
+
+ ALOGD("%s: create subdevice and get resp\n", __func__);
+ if (!virtgpu_address_space_create_context_with_subdevice(
+ handle, GoldfishAddressSpaceSubdeviceType::VirtioGpuGraphics,
+ &virtgpu_info)) {
+ ALOGE("AddressSpaceStream::create failed (create subdevice)\n");
+ virtgpu_address_space_close(handle);
+ return nullptr;
+ }
+ ALOGD("%s: create subdevice and get resp (done)\n", __func__);
+
+ struct address_space_ping request;
+ uint32_t ringSize = 0;
+ uint32_t bufferSize = 0;
+
+ request.metadata = ASG_GET_RING;
+ if (!virtgpu_address_space_ping_with_response(
+ &virtgpu_info, &request)) {
+ ALOGE("AddressSpaceStream::create failed (get ring version)\n");
+ virtgpu_address_space_close(handle);
+ return nullptr;
+ }
+ ringSize = request.size;
+
+ request.metadata = ASG_GET_BUFFER;
+ if (!virtgpu_address_space_ping_with_response(
+ &virtgpu_info, &request)) {
+ ALOGE("AddressSpaceStream::create failed (get ring version)\n");
+ virtgpu_address_space_close(handle);
+ return nullptr;
+ }
+ bufferSize = request.size;
+
+ request.metadata = ASG_SET_VERSION;
+ request.size = 1; // version 1
+
+ if (!virtgpu_address_space_ping_with_response(
+ &virtgpu_info, &request)) {
+ ALOGE("AddressSpaceStream::create failed (set version)\n");
+ virtgpu_address_space_close(handle);
+ return nullptr;
+ }
+
+ ALOGD("%s: ping returned. context ring and buffer sizes %u %u\n", __func__,
+ ringSize, bufferSize);
+
+ uint64_t hostmem_id = request.metadata;
+ uint32_t version = request.size;
+ size_t hostmem_alloc_size =
+ (size_t)(ringSize + bufferSize);
+
+ ALOGD("%s: hostmem size: %zu\n", __func__, hostmem_alloc_size);
+
+ struct address_space_virtgpu_hostmem_info hostmem_info;
+ if (!virtgpu_address_space_allocate_hostmem(
+ handle,
+ hostmem_alloc_size,
+ hostmem_id,
+ &hostmem_info)) {
+ ALOGE("AddressSpaceStream::create failed (alloc hostmem)\n");
+ virtgpu_address_space_close(handle);
+ return nullptr;
+ }
+
+ request.metadata = ASG_GET_CONFIG;
+ if (!virtgpu_address_space_ping_with_response(
+ &virtgpu_info, &request)) {
+ ALOGE("AddressSpaceStream::create failed (get config)\n");
+ virtgpu_address_space_close(handle);
+ return nullptr;
+ }
+
+ char* ringPtr = (char*)hostmem_info.ptr;
+ char* bufferPtr = ((char*)hostmem_info.ptr) + sizeof(struct asg_ring_storage);
+
+ struct asg_context context =
+ asg_context_create(
+ (char*)ringPtr, (char*)bufferPtr, bufferSize);
+
+ context.ring_config->transfer_mode = 1;
+ context.ring_config->host_consumed_pos = 0;
+ context.ring_config->guest_write_pos = 0;
+
+ struct address_space_ops ops = {
+ .open = virtgpu_address_space_open,
+ .close = virtgpu_address_space_close,
+ .ping = virtgpu_address_space_ping,
+ .allocate_hostmem = virtgpu_address_space_allocate_hostmem,
+ .ping_with_response = virtgpu_address_space_ping_with_response,
+ };
+
+ AddressSpaceStream* res =
+ new AddressSpaceStream(
+ handle, version, context,
+ 0, 0, true /* is virtio */, ops);
+
+ return res;
+}
+#endif
+
+
AddressSpaceStream::AddressSpaceStream(
address_space_handle_t handle,
uint32_t version,
struct asg_context context,
uint64_t ringOffset,
- uint64_t writeBufferOffset) :
+ uint64_t writeBufferOffset,
+ bool virtioMode,
+ struct address_space_ops ops) :
IOStream(context.ring_config->flush_interval),
+ m_virtioMode(virtioMode),
+ m_ops(ops),
m_tmpBuf(0),
m_tmpBufSize(0),
m_tmpBufXferSize(0),
@@ -163,11 +298,13 @@
}
AddressSpaceStream::~AddressSpaceStream() {
- goldfish_address_space_unmap(m_context.to_host, sizeof(struct asg_ring_storage));
- goldfish_address_space_unmap(m_context.buffer, m_writeBufferSize);
- goldfish_address_space_unclaim_shared(m_handle, m_ringOffset);
- goldfish_address_space_unclaim_shared(m_handle, m_writeBufferOffset);
- goldfish_address_space_close(m_handle);
+ if (!m_virtioMode) {
+ m_ops.unmap(m_context.to_host, sizeof(struct asg_ring_storage));
+ m_ops.unmap(m_context.buffer, m_writeBufferSize);
+ m_ops.unclaim_shared(m_handle, m_ringOffset);
+ m_ops.unclaim_shared(m_handle, m_writeBufferOffset);
+ }
+ m_ops.close(m_handle);
if (m_readBuf) free(m_readBuf);
if (m_tmpBuf) free(m_tmpBuf);
}
@@ -433,9 +570,9 @@
}
void AddressSpaceStream::notifyAvailable() {
- struct goldfish_address_space_ping request;
+ struct address_space_ping request;
request.metadata = ASG_NOTIFY_AVAILABLE;
- goldfish_address_space_ping(m_handle, &request);
+ m_ops.ping(m_handle, &request);
++m_notifs;
}
diff --git a/system/OpenglSystemCommon/AddressSpaceStream.h b/system/OpenglSystemCommon/AddressSpaceStream.h
index a4db5aa..3d60695 100644
--- a/system/OpenglSystemCommon/AddressSpaceStream.h
+++ b/system/OpenglSystemCommon/AddressSpaceStream.h
@@ -24,6 +24,7 @@
class AddressSpaceStream;
AddressSpaceStream* createAddressSpaceStream(size_t bufSize);
+AddressSpaceStream* createVirtioGpuAddressSpaceStream(size_t bufSize);
class AddressSpaceStream : public IOStream {
public:
@@ -32,7 +33,9 @@
uint32_t version,
struct asg_context context,
uint64_t ringOffset,
- uint64_t writeBufferOffset);
+ uint64_t writeBufferOffset,
+ bool virtioMode,
+ struct address_space_ops ops);
~AddressSpaceStream();
virtual size_t idealAllocSize(size_t len);
@@ -43,6 +46,11 @@
virtual int writeFully(const void *buf, size_t len);
virtual const unsigned char *commitBufferAndReadFully(size_t size, void *buf, size_t len);
+ int getRendernodeFd() const {
+ if (!m_virtioMode) return -1;
+ return m_handle;
+ }
+
private:
bool isInError() const;
ssize_t speculativeRead(unsigned char* readBuffer, size_t trySize);
@@ -54,6 +62,9 @@
void ensureType3Finished();
int type1Write(uint32_t offset, size_t size);
+ bool m_virtioMode;
+ struct address_space_ops m_ops;
+
unsigned char* m_tmpBuf;
size_t m_tmpBufSize;
size_t m_tmpBufXferSize;
diff --git a/system/OpenglSystemCommon/EmulatorFeatureInfo.h b/system/OpenglSystemCommon/EmulatorFeatureInfo.h
index f1505fe..7545e5a 100644
--- a/system/OpenglSystemCommon/EmulatorFeatureInfo.h
+++ b/system/OpenglSystemCommon/EmulatorFeatureInfo.h
@@ -154,6 +154,7 @@
HOST_CONNECTION_VIRTIO_GPU = 2,
HOST_CONNECTION_ADDRESS_SPACE = 3,
HOST_CONNECTION_VIRTIO_GPU_PIPE = 4,
+ HOST_CONNECTION_VIRTIO_GPU_ADDRESS_SPACE = 5,
};
enum GrallocType {
diff --git a/system/OpenglSystemCommon/HostConnection.cpp b/system/OpenglSystemCommon/HostConnection.cpp
index 72ea1f0..8ab05ea 100644
--- a/system/OpenglSystemCommon/HostConnection.cpp
+++ b/system/OpenglSystemCommon/HostConnection.cpp
@@ -58,6 +58,10 @@
ALOGE("%s: FATAL: Trying to create ASG stream in unsupported build\n", __func__);
abort();
}
+AddressSpaceStream* createVirtioGpuAddressSpaceStream(size_t bufSize) {
+ ALOGE("%s: FATAL: Trying to create virtgpu ASG stream in unsupported build\n", __func__);
+ abort();
+}
#endif
using goldfish_vk::VkEncoder;
@@ -112,6 +116,7 @@
if (!strcmp("virtio-gpu", transportValue)) return HOST_CONNECTION_VIRTIO_GPU;
if (!strcmp("asg", transportValue)) return HOST_CONNECTION_ADDRESS_SPACE;
if (!strcmp("virtio-gpu-pipe", transportValue)) return HOST_CONNECTION_VIRTIO_GPU_PIPE;
+ if (!strcmp("virtio-gpu-asg", transportValue)) return HOST_CONNECTION_VIRTIO_GPU_ADDRESS_SPACE;
return HOST_CONNECTION_QEMU_PIPE;
#endif
@@ -491,7 +496,7 @@
con->m_grallocType = getGrallocTypeFromProperty();
con->m_stream = stream;
con->m_rendernodeFdOwned = false;
- con->m_rendernodeFdOwned = stream->getRendernodeFd();
+ con->m_rendernodeFd = stream->getRendernodeFd();
switch (con->m_grallocType) {
case GRALLOC_TYPE_RANCHU:
con->m_grallocHelper = &m_goldfishGralloc;
@@ -509,6 +514,37 @@
con->m_processPipe = &m_goldfishProcessPipe;
break;
}
+#ifndef HOST_BUILD
+ case HOST_CONNECTION_VIRTIO_GPU_ADDRESS_SPACE: {
+ AddressSpaceStream *stream = createVirtioGpuAddressSpaceStream(STREAM_BUFFER_SIZE);
+ if (!stream) {
+ ALOGE("Failed to create virtgpu AddressSpaceStream for host connection!!!\n");
+ delete con;
+ return NULL;
+ }
+ con->m_connectionType = HOST_CONNECTION_VIRTIO_GPU_ADDRESS_SPACE;
+ con->m_grallocType = getGrallocTypeFromProperty();
+ con->m_stream = stream;
+ con->m_rendernodeFdOwned = false;
+ con->m_rendernodeFd = stream->getRendernodeFd();
+ switch (con->m_grallocType) {
+ case GRALLOC_TYPE_RANCHU:
+ con->m_grallocHelper = &m_goldfishGralloc;
+ break;
+ case GRALLOC_TYPE_MINIGBM: {
+ MinigbmGralloc* m = new MinigbmGralloc;
+ m->setFd(stream->getRendernodeFd());
+ con->m_grallocHelper = m;
+ break;
+ }
+ default:
+ ALOGE("Fatal: Unknown gralloc type 0x%x\n", con->m_grallocType);
+ abort();
+ }
+ con->m_processPipe = &m_goldfishProcessPipe;
+ break;
+ }
+#endif // !HOST_BUILD
#else
default:
break;
diff --git a/system/OpenglSystemCommon/ProcessPipe.cpp b/system/OpenglSystemCommon/ProcessPipe.cpp
index 84764f4..0d74789 100644
--- a/system/OpenglSystemCommon/ProcessPipe.cpp
+++ b/system/OpenglSystemCommon/ProcessPipe.cpp
@@ -166,7 +166,8 @@
case HOST_CONNECTION_VIRTIO_GPU:
sQemuPipeInit();
break;
- case HOST_CONNECTION_VIRTIO_GPU_PIPE: {
+ case HOST_CONNECTION_VIRTIO_GPU_PIPE:
+ case HOST_CONNECTION_VIRTIO_GPU_ADDRESS_SPACE: {
sVirtioGpuPipeStream = new VirtioGpuPipeStream(4096);
sProcUID = sVirtioGpuPipeStream->initProcessPipe();
break;
diff --git a/system/OpenglSystemCommon/address_space_graphics_types.h b/system/OpenglSystemCommon/address_space_graphics_types.h
index 1ebad34..5f0e9b6 100644
--- a/system/OpenglSystemCommon/address_space_graphics_types.h
+++ b/system/OpenglSystemCommon/address_space_graphics_types.h
@@ -342,6 +342,7 @@
// version and can proceed with a protocol that works for both.
// size (in): the version of the guest
// size (out): the version of the host
+ // metadata (out): hostmem id
// After this command runs, the consumer is
// implicitly created.
ASG_SET_VERSION = 2,
@@ -349,6 +350,9 @@
// Ping(notiy_available): Wakes up the consumer from sleep so it
// can read data via toHost
ASG_NOTIFY_AVAILABLE = 3,
+
+ // Retrieve the host config
+ ASG_GET_CONFIG = 4,
};
} // extern "C"
diff --git a/system/codecs/omx/common/Android.mk b/system/codecs/omx/common/Android.mk
index 9e233e7..4daf0b7 100644
--- a/system/codecs/omx/common/Android.mk
+++ b/system/codecs/omx/common/Android.mk
@@ -33,6 +33,15 @@
$(call emugl-import,libGoldfishAddressSpace$(GOLDFISH_OPENGL_LIB_SUFFIX))
else
$(call emugl-export,STATIC_LIBRARIES,libGoldfishAddressSpace)
+
+ifeq (true,$(BUILD_EMULATOR_VULKAN))
+
+LOCAL_CFLAGS += -DVIRTIO_GPU
+LOCAL_C_INCLUDES += external/libdrm external/minigbm/cros_gralloc
+LOCAL_SHARED_LIBRARIES += libdrm
+
+endif
+
endif
$(call emugl-end-module)
diff --git a/system/codecs/omx/common/goldfish_media_utils.cpp b/system/codecs/omx/common/goldfish_media_utils.cpp
index a2057ab..4f4ead0 100644
--- a/system/codecs/omx/common/goldfish_media_utils.cpp
+++ b/system/codecs/omx/common/goldfish_media_utils.cpp
@@ -123,7 +123,7 @@
mStartPtr = goldfish_address_space_map(mHandle, mOffset, mSize);
ALOGI("guest address is %p", mStartPtr);
- struct goldfish_address_space_ping pingInfo;
+ struct address_space_ping pingInfo;
pingInfo.metadata = GoldfishAddressSpaceSubdeviceType::Media;
pingInfo.offset = mOffset;
if (goldfish_address_space_ping(mHandle, &pingInfo) == false) {
@@ -185,7 +185,7 @@
bool GoldfishMediaTransportImpl::sendOperation(MediaCodecType type,
MediaOperation op, unsigned int offSetToStartAddr) {
- struct goldfish_address_space_ping pingInfo;
+ struct address_space_ping pingInfo;
pingInfo.metadata = makeMetadata(type, op, offSetToStartAddr);
pingInfo.offset = mOffset; // + (offSetToStartAddr);
if (goldfish_address_space_ping(mHandle, &pingInfo) == false) {
diff --git a/system/gralloc/Android.mk b/system/gralloc/Android.mk
index 8a12378..38ae394 100644
--- a/system/gralloc/Android.mk
+++ b/system/gralloc/Android.mk
@@ -19,6 +19,13 @@
ifneq (true,$(GOLDFISH_OPENGL_BUILD_FOR_HOST))
LOCAL_SHARED_LIBRARIES += libdl
+
+ifeq (true,$(BUILD_EMULATOR_VULKAN))
+LOCAL_CFLAGS += -DVIRTIO_GPU
+LOCAL_C_INCLUDES += external/libdrm external/minigbm/cros_gralloc
+LOCAL_SHARED_LIBRARIES += libdrm
+endif
+
endif
$$(call emugl-end-module)
diff --git a/system/gralloc/CMakeLists.txt b/system/gralloc/CMakeLists.txt
index b972006..21bcde2 100644
--- a/system/gralloc/CMakeLists.txt
+++ b/system/gralloc/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/gralloc/Android.mk" "09618d9293855148fb310e67065028da8c7f6dcf936b02b5695292c82ed4724e")
+android_validate_sha256("${GOLDFISH_DEVICE_ROOT}/system/gralloc/Android.mk" "c6313719aae414d05f6f4e8c6eb9039dd5cb120ae0a63818e25bfbe0cebcc702")
set(gralloc.goldfish_src gralloc_old.cpp)
android_add_library(TARGET gralloc.goldfish SHARED LICENSE Apache-2.0 SRC gralloc_old.cpp)
target_include_directories(gralloc.goldfish PRIVATE ${GOLDFISH_DEVICE_ROOT}/system/OpenglSystemCommon/bionic-include ${GOLDFISH_DEVICE_ROOT}/system/OpenglSystemCommon ${GOLDFISH_DEVICE_ROOT}/bionic/libc/private ${GOLDFISH_DEVICE_ROOT}/bionic/libc/platform ${GOLDFISH_DEVICE_ROOT}/system/vulkan_enc ${GOLDFISH_DEVICE_ROOT}/android-emu ${GOLDFISH_DEVICE_ROOT}/shared/gralloc_cb/include ${GOLDFISH_DEVICE_ROOT}/shared/GoldfishAddressSpace/include ${GOLDFISH_DEVICE_ROOT}/system/GLESv2_enc ${GOLDFISH_DEVICE_ROOT}/system/renderControl_enc ${GOLDFISH_DEVICE_ROOT}/system/GLESv1_enc ${GOLDFISH_DEVICE_ROOT}/shared/OpenglCodecCommon ${GOLDFISH_DEVICE_ROOT}/shared/qemupipe/include-types ${GOLDFISH_DEVICE_ROOT}/shared/qemupipe/include ${GOLDFISH_DEVICE_ROOT}/./host/include/libOpenglRender ${GOLDFISH_DEVICE_ROOT}/./system/include ${GOLDFISH_DEVICE_ROOT}/./../../../external/qemu/android/android-emugl/guest)
@@ -11,7 +11,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/gralloc/Android.mk" "09618d9293855148fb310e67065028da8c7f6dcf936b02b5695292c82ed4724e")
+android_validate_sha256("${GOLDFISH_DEVICE_ROOT}/system/gralloc/Android.mk" "c6313719aae414d05f6f4e8c6eb9039dd5cb120ae0a63818e25bfbe0cebcc702")
set(gralloc.ranchu_src gralloc_old.cpp)
android_add_library(TARGET gralloc.ranchu SHARED LICENSE Apache-2.0 SRC gralloc_old.cpp)
target_include_directories(gralloc.ranchu PRIVATE ${GOLDFISH_DEVICE_ROOT}/system/OpenglSystemCommon/bionic-include ${GOLDFISH_DEVICE_ROOT}/system/OpenglSystemCommon ${GOLDFISH_DEVICE_ROOT}/bionic/libc/private ${GOLDFISH_DEVICE_ROOT}/bionic/libc/platform ${GOLDFISH_DEVICE_ROOT}/system/vulkan_enc ${GOLDFISH_DEVICE_ROOT}/android-emu ${GOLDFISH_DEVICE_ROOT}/shared/gralloc_cb/include ${GOLDFISH_DEVICE_ROOT}/shared/GoldfishAddressSpace/include ${GOLDFISH_DEVICE_ROOT}/system/GLESv2_enc ${GOLDFISH_DEVICE_ROOT}/system/renderControl_enc ${GOLDFISH_DEVICE_ROOT}/system/GLESv1_enc ${GOLDFISH_DEVICE_ROOT}/shared/OpenglCodecCommon ${GOLDFISH_DEVICE_ROOT}/shared/qemupipe/include-types ${GOLDFISH_DEVICE_ROOT}/shared/qemupipe/include ${GOLDFISH_DEVICE_ROOT}/./host/include/libOpenglRender ${GOLDFISH_DEVICE_ROOT}/./system/include ${GOLDFISH_DEVICE_ROOT}/./../../../external/qemu/android/android-emugl/guest)
diff --git a/system/hals/Android.mk b/system/hals/Android.mk
index 3cdb4bf..1641d23 100644
--- a/system/hals/Android.mk
+++ b/system/hals/Android.mk
@@ -45,6 +45,10 @@
device/generic/goldfish-opengl/host/include/libOpenglRender \
device/generic/goldfish-opengl/system/renderControl_enc \
+LOCAL_CFLAGS += -DVIRTIO_GPU
+LOCAL_C_INCLUDES += external/libdrm external/minigbm/cros_gralloc
+LOCAL_SHARED_LIBRARIES += libdrm
+
include $(BUILD_EXECUTABLE)
include $(CLEAR_VARS)
@@ -78,5 +82,9 @@
device/generic/goldfish-opengl/host/include/libOpenglRender \
device/generic/goldfish-opengl/system/renderControl_enc \
+LOCAL_CFLAGS += -DVIRTIO_GPU
+LOCAL_C_INCLUDES += external/libdrm external/minigbm/cros_gralloc
+LOCAL_SHARED_LIBRARIES += libdrm
+
include $(BUILD_SHARED_LIBRARY)