• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "VulkanStream.h"
15 
16 #include "IOStream.h"
17 
18 #include "base/BumpPool.h"
19 
20 #include "host-common/feature_control.h"
21 #include "host-common/GfxstreamFatalError.h"
22 
23 #include <vector>
24 
25 #include <inttypes.h>
26 
27 #define E(fmt,...) fprintf(stderr, fmt "\n", ##__VA_ARGS__)
28 
29 using emugl::ABORT_REASON_OTHER;
30 using emugl::FatalError;
31 
32 namespace goldfish_vk {
33 
VulkanStream(IOStream * stream)34 VulkanStream::VulkanStream(IOStream *stream) : mStream(stream) {
35     unsetHandleMapping();
36 
37     if (feature_is_enabled(kFeature_VulkanNullOptionalStrings)) {
38         mFeatureBits |= VULKAN_STREAM_FEATURE_NULL_OPTIONAL_STRINGS_BIT;
39     }
40     if (feature_is_enabled(kFeature_VulkanIgnoredHandles)) {
41         mFeatureBits |= VULKAN_STREAM_FEATURE_IGNORED_HANDLES_BIT;
42     }
43     if (feature_is_enabled(kFeature_VulkanShaderFloat16Int8)) {
44         mFeatureBits |= VULKAN_STREAM_FEATURE_SHADER_FLOAT16_INT8_BIT;
45     }
46 }
47 
48 VulkanStream::~VulkanStream() = default;
49 
setStream(IOStream * stream)50 void VulkanStream::setStream(IOStream* stream) {
51     mStream = stream;
52 }
53 
valid()54 bool VulkanStream::valid() {
55     return true;
56 }
57 
alloc(void ** ptrAddr,size_t bytes)58 void VulkanStream::alloc(void** ptrAddr, size_t bytes) {
59     if (!bytes) {
60         *ptrAddr = nullptr;
61         return;
62     }
63 
64     *ptrAddr = mPool.alloc(bytes);
65 
66     if (!*ptrAddr) {
67         GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER)) <<
68                 "alloc failed. Wanted size: " << bytes;
69     }
70 }
71 
loadStringInPlace(char ** forOutput)72 void VulkanStream::loadStringInPlace(char** forOutput) {
73     size_t len = getBe32();
74 
75     alloc((void**)forOutput, len + 1);
76 
77     memset(*forOutput, 0x0, len + 1);
78 
79     if (len > 0) read(*forOutput, len);
80 }
81 
loadStringArrayInPlace(char *** forOutput)82 void VulkanStream::loadStringArrayInPlace(char*** forOutput) {
83     size_t count = getBe32();
84 
85     if (!count) {
86         *forOutput = nullptr;
87         return;
88     }
89 
90     alloc((void**)forOutput, count * sizeof(char*));
91 
92     char **stringsForOutput = *forOutput;
93 
94     for (size_t i = 0; i < count; i++) {
95         loadStringInPlace(stringsForOutput + i);
96     }
97 }
98 
loadStringInPlaceWithStreamPtr(char ** forOutput,uint8_t ** streamPtr)99 void VulkanStream::loadStringInPlaceWithStreamPtr(char** forOutput, uint8_t** streamPtr) {
100     uint32_t len;
101     memcpy(&len, *streamPtr, sizeof(uint32_t));
102     *streamPtr += sizeof(uint32_t);
103     android::base::Stream::fromBe32((uint8_t*)&len);
104 
105     if (len == UINT32_MAX) {
106         GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER)) <<
107                 "VulkanStream can't allocate UINT32_MAX bytes";
108     }
109 
110     alloc((void**)forOutput, len + 1);
111 
112     if (len > 0) {
113         memcpy(*forOutput, *streamPtr, len);
114         *streamPtr += len;
115     }
116     (*forOutput)[len] = 0;
117 }
118 
loadStringArrayInPlaceWithStreamPtr(char *** forOutput,uint8_t ** streamPtr)119 void VulkanStream::loadStringArrayInPlaceWithStreamPtr(char*** forOutput, uint8_t** streamPtr) {
120     uint32_t count;
121     memcpy(&count, *streamPtr, sizeof(uint32_t));
122     *streamPtr += sizeof(uint32_t);
123     android::base::Stream::fromBe32((uint8_t*)&count);
124 
125     if (!count) {
126         *forOutput = nullptr;
127         return;
128     }
129 
130     alloc((void**)forOutput, count * sizeof(char*));
131 
132     char **stringsForOutput = *forOutput;
133 
134     for (size_t i = 0; i < count; i++) {
135         loadStringInPlaceWithStreamPtr(stringsForOutput + i, streamPtr);
136     }
137 }
138 
read(void * buffer,size_t size)139 ssize_t VulkanStream::read(void *buffer, size_t size) {
140     commitWrite();
141     if (!mStream->readFully(buffer, size)) {
142         GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
143             << "Could not read back " << size << " bytes";
144     }
145     return size;
146 }
147 
remainingWriteBufferSize() const148 size_t VulkanStream::remainingWriteBufferSize() const {
149     return mWriteBuffer.size() - mWritePos;
150 }
151 
bufferedWrite(const void * buffer,size_t size)152 ssize_t VulkanStream::bufferedWrite(const void *buffer, size_t size) {
153     if (size > remainingWriteBufferSize()) {
154         mWriteBuffer.resize((mWritePos + size) << 1);
155     }
156     memcpy(mWriteBuffer.data() + mWritePos, buffer, size);
157     mWritePos += size;
158     return size;
159 }
160 
write(const void * buffer,size_t size)161 ssize_t VulkanStream::write(const void *buffer, size_t size) {
162     return bufferedWrite(buffer, size);
163 }
164 
commitWrite()165 void VulkanStream::commitWrite() {
166     if (!valid()) {
167         GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER)) <<
168                             "Tried to commit write to vulkan pipe with invalid pipe!";
169     }
170 
171     int written =
172         mStream->writeFully(mWriteBuffer.data(), mWritePos);
173 
174     if (written) {
175         GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
176             << "Did not write exactly " << mWritePos << " bytes!";
177     }
178     mWritePos = 0;
179 }
180 
clearPool()181 void VulkanStream::clearPool() {
182     mPool.freeAll();
183 }
184 
setHandleMapping(VulkanHandleMapping * mapping)185 void VulkanStream::setHandleMapping(VulkanHandleMapping* mapping) {
186     mCurrentHandleMapping = mapping;
187 }
188 
unsetHandleMapping()189 void VulkanStream::unsetHandleMapping() {
190     mCurrentHandleMapping = &mDefaultHandleMapping;
191 }
192 
handleMapping() const193 VulkanHandleMapping* VulkanStream::handleMapping() const {
194     return mCurrentHandleMapping;
195 }
196 
getFeatureBits() const197 uint32_t VulkanStream::getFeatureBits() const {
198     return mFeatureBits;
199 }
200 
pool()201 android::base::BumpPool* VulkanStream::pool() {
202     return &mPool;
203 }
204 
VulkanMemReadingStream(uint8_t * start)205 VulkanMemReadingStream::VulkanMemReadingStream(uint8_t* start)
206     : VulkanStream(nullptr), mStart(start) {}
207 
~VulkanMemReadingStream()208 VulkanMemReadingStream::~VulkanMemReadingStream() { }
209 
setBuf(uint8_t * buf)210 void VulkanMemReadingStream::setBuf(uint8_t* buf) {
211     mStart = buf;
212     mReadPos = 0;
213     resetTrace();
214 }
215 
getBuf()216 uint8_t* VulkanMemReadingStream::getBuf() {
217     return mStart;
218 }
219 
setReadPos(uintptr_t pos)220 void VulkanMemReadingStream::setReadPos(uintptr_t pos) {
221     mReadPos = pos;
222 }
223 
read(void * buffer,size_t size)224 ssize_t VulkanMemReadingStream::read(void* buffer, size_t size) {
225     memcpy(buffer, mStart + mReadPos, size);
226     mReadPos += size;
227     return size;
228 }
229 
write(const void * buffer,size_t size)230 ssize_t VulkanMemReadingStream::write(const void* buffer, size_t size) {
231     GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER)) <<
232             "VulkanMemReadingStream does not support writing";
233 }
234 
beginTrace()235 uint8_t* VulkanMemReadingStream::beginTrace() {
236     resetTrace();
237     return mTraceStart;
238 }
239 
endTrace()240 size_t VulkanMemReadingStream::endTrace() {
241     uintptr_t current = (uintptr_t)(mStart + mReadPos);
242     size_t res = (size_t)(current - (uintptr_t)mTraceStart);
243     return res;
244 }
245 
resetTrace()246 void VulkanMemReadingStream::resetTrace() {
247     mTraceStart = mStart + mReadPos;
248 }
249 
250 } // namespace goldfish_vk
251