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