1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker * Copyright 2023 Google
3*61046927SAndroid Build Coastguard Worker * SPDX-License-Identifier: MIT
4*61046927SAndroid Build Coastguard Worker */
5*61046927SAndroid Build Coastguard Worker
6*61046927SAndroid Build Coastguard Worker #include "VirtioGpuAddressSpaceStream.h"
7*61046927SAndroid Build Coastguard Worker
8*61046927SAndroid Build Coastguard Worker #include <errno.h>
9*61046927SAndroid Build Coastguard Worker
10*61046927SAndroid Build Coastguard Worker #include "util/log.h"
11*61046927SAndroid Build Coastguard Worker
GetRingParamsFromCapset(enum VirtGpuCapset capset,const VirtGpuCaps & caps,uint32_t & ringSize,uint32_t & bufferSize,uint32_t & blobAlignment)12*61046927SAndroid Build Coastguard Worker static bool GetRingParamsFromCapset(enum VirtGpuCapset capset, const VirtGpuCaps& caps,
13*61046927SAndroid Build Coastguard Worker uint32_t& ringSize, uint32_t& bufferSize,
14*61046927SAndroid Build Coastguard Worker uint32_t& blobAlignment) {
15*61046927SAndroid Build Coastguard Worker switch (capset) {
16*61046927SAndroid Build Coastguard Worker case kCapsetGfxStreamVulkan:
17*61046927SAndroid Build Coastguard Worker ringSize = caps.vulkanCapset.ringSize;
18*61046927SAndroid Build Coastguard Worker bufferSize = caps.vulkanCapset.bufferSize;
19*61046927SAndroid Build Coastguard Worker blobAlignment = caps.vulkanCapset.blobAlignment;
20*61046927SAndroid Build Coastguard Worker break;
21*61046927SAndroid Build Coastguard Worker case kCapsetGfxStreamMagma:
22*61046927SAndroid Build Coastguard Worker ringSize = caps.magmaCapset.ringSize;
23*61046927SAndroid Build Coastguard Worker bufferSize = caps.magmaCapset.bufferSize;
24*61046927SAndroid Build Coastguard Worker blobAlignment = caps.magmaCapset.blobAlignment;
25*61046927SAndroid Build Coastguard Worker break;
26*61046927SAndroid Build Coastguard Worker case kCapsetGfxStreamGles:
27*61046927SAndroid Build Coastguard Worker ringSize = caps.glesCapset.ringSize;
28*61046927SAndroid Build Coastguard Worker bufferSize = caps.glesCapset.bufferSize;
29*61046927SAndroid Build Coastguard Worker blobAlignment = caps.glesCapset.blobAlignment;
30*61046927SAndroid Build Coastguard Worker break;
31*61046927SAndroid Build Coastguard Worker case kCapsetGfxStreamComposer:
32*61046927SAndroid Build Coastguard Worker ringSize = caps.composerCapset.ringSize;
33*61046927SAndroid Build Coastguard Worker bufferSize = caps.composerCapset.bufferSize;
34*61046927SAndroid Build Coastguard Worker blobAlignment = caps.composerCapset.blobAlignment;
35*61046927SAndroid Build Coastguard Worker break;
36*61046927SAndroid Build Coastguard Worker default:
37*61046927SAndroid Build Coastguard Worker return false;
38*61046927SAndroid Build Coastguard Worker }
39*61046927SAndroid Build Coastguard Worker
40*61046927SAndroid Build Coastguard Worker return true;
41*61046927SAndroid Build Coastguard Worker }
42*61046927SAndroid Build Coastguard Worker
virtgpu_address_space_open()43*61046927SAndroid Build Coastguard Worker address_space_handle_t virtgpu_address_space_open() {
44*61046927SAndroid Build Coastguard Worker return (address_space_handle_t)(-EINVAL);
45*61046927SAndroid Build Coastguard Worker }
46*61046927SAndroid Build Coastguard Worker
virtgpu_address_space_close(address_space_handle_t)47*61046927SAndroid Build Coastguard Worker void virtgpu_address_space_close(address_space_handle_t) {
48*61046927SAndroid Build Coastguard Worker // Handle opened by VirtioGpuDevice wrapper
49*61046927SAndroid Build Coastguard Worker }
50*61046927SAndroid Build Coastguard Worker
virtgpu_address_space_ping(address_space_handle_t,struct address_space_ping * info)51*61046927SAndroid Build Coastguard Worker bool virtgpu_address_space_ping(address_space_handle_t, struct address_space_ping* info) {
52*61046927SAndroid Build Coastguard Worker int ret;
53*61046927SAndroid Build Coastguard Worker struct VirtGpuExecBuffer exec = {};
54*61046927SAndroid Build Coastguard Worker VirtGpuDevice* instance = VirtGpuDevice::getInstance();
55*61046927SAndroid Build Coastguard Worker struct gfxstreamContextPing ping = {};
56*61046927SAndroid Build Coastguard Worker
57*61046927SAndroid Build Coastguard Worker ping.hdr.opCode = GFXSTREAM_CONTEXT_PING;
58*61046927SAndroid Build Coastguard Worker ping.resourceId = info->resourceId;
59*61046927SAndroid Build Coastguard Worker
60*61046927SAndroid Build Coastguard Worker exec.command = static_cast<void*>(&ping);
61*61046927SAndroid Build Coastguard Worker exec.command_size = sizeof(ping);
62*61046927SAndroid Build Coastguard Worker
63*61046927SAndroid Build Coastguard Worker ret = instance->execBuffer(exec, nullptr);
64*61046927SAndroid Build Coastguard Worker if (ret)
65*61046927SAndroid Build Coastguard Worker return false;
66*61046927SAndroid Build Coastguard Worker
67*61046927SAndroid Build Coastguard Worker return true;
68*61046927SAndroid Build Coastguard Worker }
69*61046927SAndroid Build Coastguard Worker
createVirtioGpuAddressSpaceStream(enum VirtGpuCapset capset)70*61046927SAndroid Build Coastguard Worker AddressSpaceStream* createVirtioGpuAddressSpaceStream(enum VirtGpuCapset capset) {
71*61046927SAndroid Build Coastguard Worker VirtGpuResourcePtr pipe, blob;
72*61046927SAndroid Build Coastguard Worker VirtGpuResourceMappingPtr pipeMapping, blobMapping;
73*61046927SAndroid Build Coastguard Worker struct VirtGpuExecBuffer exec = {};
74*61046927SAndroid Build Coastguard Worker struct VirtGpuCreateBlob blobCreate = {};
75*61046927SAndroid Build Coastguard Worker struct gfxstreamContextCreate contextCreate = {};
76*61046927SAndroid Build Coastguard Worker
77*61046927SAndroid Build Coastguard Worker uint32_t ringSize = 0;
78*61046927SAndroid Build Coastguard Worker uint32_t bufferSize = 0;
79*61046927SAndroid Build Coastguard Worker uint32_t blobAlignment = 0;
80*61046927SAndroid Build Coastguard Worker
81*61046927SAndroid Build Coastguard Worker char* blobAddr, *bufferPtr;
82*61046927SAndroid Build Coastguard Worker int ret;
83*61046927SAndroid Build Coastguard Worker
84*61046927SAndroid Build Coastguard Worker VirtGpuDevice* instance = VirtGpuDevice::getInstance();
85*61046927SAndroid Build Coastguard Worker auto caps = instance->getCaps();
86*61046927SAndroid Build Coastguard Worker
87*61046927SAndroid Build Coastguard Worker if (!GetRingParamsFromCapset(capset, caps, ringSize, bufferSize, blobAlignment)) {
88*61046927SAndroid Build Coastguard Worker mesa_loge("Failed to get ring parameters");
89*61046927SAndroid Build Coastguard Worker return nullptr;
90*61046927SAndroid Build Coastguard Worker }
91*61046927SAndroid Build Coastguard Worker
92*61046927SAndroid Build Coastguard Worker blobCreate.blobId = 0;
93*61046927SAndroid Build Coastguard Worker blobCreate.blobMem = kBlobMemHost3d;
94*61046927SAndroid Build Coastguard Worker blobCreate.flags = kBlobFlagMappable;
95*61046927SAndroid Build Coastguard Worker blobCreate.size = ALIGN_POT(ringSize + bufferSize, blobAlignment);
96*61046927SAndroid Build Coastguard Worker blob = instance->createBlob(blobCreate);
97*61046927SAndroid Build Coastguard Worker if (!blob)
98*61046927SAndroid Build Coastguard Worker return nullptr;
99*61046927SAndroid Build Coastguard Worker
100*61046927SAndroid Build Coastguard Worker // Context creation command
101*61046927SAndroid Build Coastguard Worker contextCreate.hdr.opCode = GFXSTREAM_CONTEXT_CREATE;
102*61046927SAndroid Build Coastguard Worker contextCreate.resourceId = blob->getResourceHandle();
103*61046927SAndroid Build Coastguard Worker
104*61046927SAndroid Build Coastguard Worker exec.command = static_cast<void*>(&contextCreate);
105*61046927SAndroid Build Coastguard Worker exec.command_size = sizeof(contextCreate);
106*61046927SAndroid Build Coastguard Worker
107*61046927SAndroid Build Coastguard Worker ret = instance->execBuffer(exec, blob.get());
108*61046927SAndroid Build Coastguard Worker if (ret)
109*61046927SAndroid Build Coastguard Worker return nullptr;
110*61046927SAndroid Build Coastguard Worker
111*61046927SAndroid Build Coastguard Worker // Wait occurs on global timeline -- should we use context specific one?
112*61046927SAndroid Build Coastguard Worker ret = blob->wait();
113*61046927SAndroid Build Coastguard Worker if (ret)
114*61046927SAndroid Build Coastguard Worker return nullptr;
115*61046927SAndroid Build Coastguard Worker
116*61046927SAndroid Build Coastguard Worker blobMapping = blob->createMapping();
117*61046927SAndroid Build Coastguard Worker if (!blobMapping)
118*61046927SAndroid Build Coastguard Worker return nullptr;
119*61046927SAndroid Build Coastguard Worker
120*61046927SAndroid Build Coastguard Worker blobAddr = reinterpret_cast<char*>(blobMapping->asRawPtr());
121*61046927SAndroid Build Coastguard Worker
122*61046927SAndroid Build Coastguard Worker bufferPtr = blobAddr + sizeof(struct asg_ring_storage);
123*61046927SAndroid Build Coastguard Worker struct asg_context context = asg_context_create(blobAddr, bufferPtr, bufferSize);
124*61046927SAndroid Build Coastguard Worker
125*61046927SAndroid Build Coastguard Worker context.ring_config->transfer_mode = 1;
126*61046927SAndroid Build Coastguard Worker context.ring_config->host_consumed_pos = 0;
127*61046927SAndroid Build Coastguard Worker context.ring_config->guest_write_pos = 0;
128*61046927SAndroid Build Coastguard Worker
129*61046927SAndroid Build Coastguard Worker struct address_space_ops ops = {
130*61046927SAndroid Build Coastguard Worker .open = virtgpu_address_space_open,
131*61046927SAndroid Build Coastguard Worker .close = virtgpu_address_space_close,
132*61046927SAndroid Build Coastguard Worker .ping = virtgpu_address_space_ping,
133*61046927SAndroid Build Coastguard Worker };
134*61046927SAndroid Build Coastguard Worker
135*61046927SAndroid Build Coastguard Worker AddressSpaceStream* res =
136*61046927SAndroid Build Coastguard Worker new AddressSpaceStream((address_space_handle_t)(-1), 1, context, 0, 0, ops);
137*61046927SAndroid Build Coastguard Worker
138*61046927SAndroid Build Coastguard Worker res->setMapping(blobMapping);
139*61046927SAndroid Build Coastguard Worker res->setResourceId(contextCreate.resourceId);
140*61046927SAndroid Build Coastguard Worker return res;
141*61046927SAndroid Build Coastguard Worker }
142