1 // Copyright (C) 2018 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 #include "VulkanStreamGuest.h"
15
16 #include "util/log.h"
17
18 namespace gfxstream {
19 namespace vk {
20
VulkanStreamGuest(gfxstream::guest::IOStream * stream)21 VulkanStreamGuest::VulkanStreamGuest(gfxstream::guest::IOStream* stream) : mStream(stream) {
22 unsetHandleMapping();
23 mFeatureBits = ResourceTracker::get()->getStreamFeatures();
24 }
25
26 VulkanStreamGuest::~VulkanStreamGuest() = default;
27
valid()28 bool VulkanStreamGuest::valid() { return true; }
29
alloc(void ** ptrAddr,size_t bytes)30 void VulkanStreamGuest::alloc(void** ptrAddr, size_t bytes) {
31 if (!bytes) {
32 *ptrAddr = nullptr;
33 return;
34 }
35
36 *ptrAddr = mPool.alloc(bytes);
37 }
38
loadStringInPlace(char ** forOutput)39 void VulkanStreamGuest::loadStringInPlace(char** forOutput) {
40 size_t len = getBe32();
41
42 alloc((void**)forOutput, len + 1);
43
44 memset(*forOutput, 0x0, len + 1);
45
46 if (len > 0) read(*forOutput, len);
47 }
48
loadStringArrayInPlace(char *** forOutput)49 void VulkanStreamGuest::loadStringArrayInPlace(char*** forOutput) {
50 size_t count = getBe32();
51
52 if (!count) {
53 *forOutput = nullptr;
54 return;
55 }
56
57 alloc((void**)forOutput, count * sizeof(char*));
58
59 char** stringsForOutput = *forOutput;
60
61 for (size_t i = 0; i < count; i++) {
62 loadStringInPlace(stringsForOutput + i);
63 }
64 }
65
loadStringInPlaceWithStreamPtr(char ** forOutput,uint8_t ** streamPtr)66 void VulkanStreamGuest::loadStringInPlaceWithStreamPtr(char** forOutput, uint8_t** streamPtr) {
67 uint32_t len;
68 memcpy(&len, *streamPtr, sizeof(uint32_t));
69 *streamPtr += sizeof(uint32_t);
70 gfxstream::guest::Stream::fromBe32((uint8_t*)&len);
71
72 alloc((void**)forOutput, len + 1);
73
74 memset(*forOutput, 0x0, len + 1);
75
76 if (len > 0) {
77 memcpy(*forOutput, *streamPtr, len);
78 *streamPtr += len;
79 }
80 }
81
loadStringArrayInPlaceWithStreamPtr(char *** forOutput,uint8_t ** streamPtr)82 void VulkanStreamGuest::loadStringArrayInPlaceWithStreamPtr(char*** forOutput,
83 uint8_t** streamPtr) {
84 uint32_t count;
85 memcpy(&count, *streamPtr, sizeof(uint32_t));
86 *streamPtr += sizeof(uint32_t);
87 gfxstream::guest::Stream::fromBe32((uint8_t*)&count);
88 if (!count) {
89 *forOutput = nullptr;
90 return;
91 }
92
93 alloc((void**)forOutput, count * sizeof(char*));
94
95 char** stringsForOutput = *forOutput;
96
97 for (size_t i = 0; i < count; i++) {
98 loadStringInPlaceWithStreamPtr(stringsForOutput + i, streamPtr);
99 }
100 }
101
read(void * buffer,size_t size)102 ssize_t VulkanStreamGuest::read(void* buffer, size_t size) {
103 if (!mStream->readback(buffer, size)) {
104 mesa_loge("FATAL: Could not read back %zu bytes", size);
105 abort();
106 }
107 return size;
108 }
109
write(const void * buffer,size_t size)110 ssize_t VulkanStreamGuest::write(const void* buffer, size_t size) {
111 uint8_t* streamBuf = (uint8_t*)mStream->alloc(size);
112 memcpy(streamBuf, buffer, size);
113 return size;
114 }
115
writeLarge(const void * buffer,size_t size)116 void VulkanStreamGuest::writeLarge(const void* buffer, size_t size) {
117 mStream->writeFullyAsync(buffer, size);
118 }
119
clearPool()120 void VulkanStreamGuest::clearPool() { mPool.freeAll(); }
121
setHandleMapping(VulkanHandleMapping * mapping)122 void VulkanStreamGuest::setHandleMapping(VulkanHandleMapping* mapping) {
123 mCurrentHandleMapping = mapping;
124 }
125
unsetHandleMapping()126 void VulkanStreamGuest::unsetHandleMapping() { mCurrentHandleMapping = &mDefaultHandleMapping; }
127
handleMapping() const128 VulkanHandleMapping* VulkanStreamGuest::handleMapping() const { return mCurrentHandleMapping; }
129
flush()130 void VulkanStreamGuest::flush() {
131 AEMU_SCOPED_TRACE("VulkanStreamGuest device write");
132 mStream->flush();
133 }
134
getFeatureBits() const135 uint32_t VulkanStreamGuest::getFeatureBits() const { return mFeatureBits; }
136
incStreamRef()137 void VulkanStreamGuest::incStreamRef() { mStream->incRef(); }
138
decStreamRef()139 bool VulkanStreamGuest::decStreamRef() { return mStream->decRef(); }
140
reserve(size_t size)141 uint8_t* VulkanStreamGuest::reserve(size_t size) { return (uint8_t*)mStream->alloc(size); }
142
VulkanCountingStream()143 VulkanCountingStream::VulkanCountingStream() : VulkanStreamGuest(nullptr) {}
144 VulkanCountingStream::~VulkanCountingStream() = default;
145
read(void *,size_t size)146 ssize_t VulkanCountingStream::read(void*, size_t size) {
147 m_read += size;
148 return size;
149 }
150
write(const void *,size_t size)151 ssize_t VulkanCountingStream::write(const void*, size_t size) {
152 m_written += size;
153 return size;
154 }
155
rewind()156 void VulkanCountingStream::rewind() {
157 m_written = 0;
158 m_read = 0;
159 }
160
161 } // namespace vk
162 } // namespace gfxstream
163