blob: a3ff4567c0c54d6d5577138c16eca4b8c02c8625 [file] [log] [blame]
Lingfeng Yang71b596b2018-11-07 18:03:25 -08001// Copyright (C) 2018 The Android Open Source Project
2// Copyright (C) 2018 Google Inc.
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15
Lingfeng Yang71b596b2018-11-07 18:03:25 -080016#include "ResourceTracker.h"
17
Lingfeng Yang31754632018-12-21 18:24:55 -080018#include "../OpenglSystemCommon/EmulatorFeatureInfo.h"
Lingfeng Yang58b89c82018-12-25 11:23:21 -080019#include "HostVisibleMemoryVirtualization.h"
Lingfeng Yang71b596b2018-11-07 18:03:25 -080020#include "Resources.h"
Lingfeng Yang131d5a42018-11-30 12:00:33 -080021#include "VkEncoder.h"
Lingfeng Yang71b596b2018-11-07 18:03:25 -080022
Lingfeng Yang131d5a42018-11-30 12:00:33 -080023#include "android/base/AlignedBuf.h"
Lingfeng Yang6ab1b0d2018-11-27 23:36:03 -080024#include "android/base/synchronization/AndroidLock.h"
25
Lingfeng Yangdef88ba2018-12-13 12:43:17 -080026#include "gralloc_cb.h"
Lingfeng Yang236abc92018-12-21 20:19:33 -080027#include "goldfish_address_space.h"
Lingfeng Yangdef88ba2018-12-13 12:43:17 -080028#include "goldfish_vk_private_defs.h"
29
Lingfeng Yang6ab1b0d2018-11-27 23:36:03 -080030#include <unordered_map>
31
Lingfeng Yang131d5a42018-11-30 12:00:33 -080032#include <log/log.h>
Lingfeng Yangdef88ba2018-12-13 12:43:17 -080033#include <stdlib.h>
34#include <sync/sync.h>
Lingfeng Yang131d5a42018-11-30 12:00:33 -080035
36#define RESOURCE_TRACKER_DEBUG 0
37
38#if RESOURCE_TRACKER_DEBUG
39#define D(fmt,...) ALOGD("%s: " fmt, __func__, ##__VA_ARGS__);
40#else
41#ifndef D
42#define D(fmt,...)
43#endif
44#endif
45
46using android::aligned_buf_alloc;
47using android::aligned_buf_free;
Lingfeng Yang6ab1b0d2018-11-27 23:36:03 -080048using android::base::guest::AutoLock;
49using android::base::guest::Lock;
50
Lingfeng Yang71b596b2018-11-07 18:03:25 -080051namespace goldfish_vk {
52
Lingfeng Yang2285df12018-11-17 16:25:11 -080053#define MAKE_HANDLE_MAPPING_FOREACH(type_name, map_impl, map_to_u64_impl, map_from_u64_impl) \
54 void mapHandles_##type_name(type_name* handles, size_t count) override { \
55 for (size_t i = 0; i < count; ++i) { \
56 map_impl; \
57 } \
58 } \
59 void mapHandles_##type_name##_u64(const type_name* handles, uint64_t* handle_u64s, size_t count) override { \
60 for (size_t i = 0; i < count; ++i) { \
61 map_to_u64_impl; \
62 } \
63 } \
64 void mapHandles_u64_##type_name(const uint64_t* handle_u64s, type_name* handles, size_t count) override { \
65 for (size_t i = 0; i < count; ++i) { \
66 map_from_u64_impl; \
67 } \
68 } \
69
70#define DEFINE_RESOURCE_TRACKING_CLASS(class_name, impl) \
71class class_name : public VulkanHandleMapping { \
72public: \
73 virtual ~class_name() { } \
74 GOLDFISH_VK_LIST_HANDLE_TYPES(impl) \
75}; \
76
77#define CREATE_MAPPING_IMPL_FOR_TYPE(type_name) \
78 MAKE_HANDLE_MAPPING_FOREACH(type_name, \
Lingfeng Yang6ab1b0d2018-11-27 23:36:03 -080079 handles[i] = new_from_host_##type_name(handles[i]); ResourceTracker::get()->register_##type_name(handles[i]);, \
Lingfeng Yang04a57192018-12-20 14:06:45 -080080 handle_u64s[i] = (uint64_t)new_from_host_##type_name(handles[i]), \
81 handles[i] = (type_name)new_from_host_u64_##type_name(handle_u64s[i]); ResourceTracker::get()->register_##type_name(handles[i]);)
Lingfeng Yang2285df12018-11-17 16:25:11 -080082
83#define UNWRAP_MAPPING_IMPL_FOR_TYPE(type_name) \
84 MAKE_HANDLE_MAPPING_FOREACH(type_name, \
85 handles[i] = get_host_##type_name(handles[i]), \
Lingfeng Yang04a57192018-12-20 14:06:45 -080086 handle_u64s[i] = (uint64_t)get_host_u64_##type_name(handles[i]), \
87 handles[i] = (type_name)get_host_##type_name((type_name)handle_u64s[i]))
Lingfeng Yang2285df12018-11-17 16:25:11 -080088
89#define DESTROY_MAPPING_IMPL_FOR_TYPE(type_name) \
90 MAKE_HANDLE_MAPPING_FOREACH(type_name, \
Lingfeng Yang6ab1b0d2018-11-27 23:36:03 -080091 ResourceTracker::get()->unregister_##type_name(handles[i]); delete_goldfish_##type_name(handles[i]), \
Lingfeng Yang2285df12018-11-17 16:25:11 -080092 (void)handle_u64s[i]; delete_goldfish_##type_name(handles[i]), \
Lingfeng Yang04a57192018-12-20 14:06:45 -080093 (void)handles[i]; delete_goldfish_##type_name((type_name)handle_u64s[i]))
Lingfeng Yang2285df12018-11-17 16:25:11 -080094
95DEFINE_RESOURCE_TRACKING_CLASS(CreateMapping, CREATE_MAPPING_IMPL_FOR_TYPE)
96DEFINE_RESOURCE_TRACKING_CLASS(UnwrapMapping, UNWRAP_MAPPING_IMPL_FOR_TYPE)
97DEFINE_RESOURCE_TRACKING_CLASS(DestroyMapping, DESTROY_MAPPING_IMPL_FOR_TYPE)
Lingfeng Yang71b596b2018-11-07 18:03:25 -080098
99class ResourceTracker::Impl {
100public:
101 Impl() = default;
102 CreateMapping createMapping;
103 UnwrapMapping unwrapMapping;
104 DestroyMapping destroyMapping;
Lingfeng Yang2285df12018-11-17 16:25:11 -0800105 DefaultHandleMapping defaultMapping;
Lingfeng Yang6ab1b0d2018-11-27 23:36:03 -0800106
107#define HANDLE_DEFINE_TRIVIAL_INFO_STRUCT(type) \
108 struct type##_Info { \
109 uint32_t unused; \
110 }; \
111
112 GOLDFISH_VK_LIST_TRIVIAL_HANDLE_TYPES(HANDLE_DEFINE_TRIVIAL_INFO_STRUCT)
113
114 struct VkDevice_Info {
115 VkPhysicalDevice physdev;
116 VkPhysicalDeviceProperties props;
117 VkPhysicalDeviceMemoryProperties memProps;
118 };
119
120 struct VkDeviceMemory_Info {
Lingfeng Yangdef88ba2018-12-13 12:43:17 -0800121 VkDeviceSize allocationSize = 0;
122 VkDeviceSize mappedSize = 0;
123 uint8_t* mappedPtr = nullptr;
124 uint32_t memoryTypeIndex = 0;
Lingfeng Yang236abc92018-12-21 20:19:33 -0800125 bool directMapped = false;
126 std::unique_ptr<GoldfishAddressSpaceBlock>
127 goldfishAddressSpaceBlock = {};
Lingfeng Yang6ab1b0d2018-11-27 23:36:03 -0800128 };
129
130#define HANDLE_REGISTER_IMPL_IMPL(type) \
131 std::unordered_map<type, type##_Info> info_##type; \
132 void register_##type(type obj) { \
133 AutoLock lock(mLock); \
134 info_##type[obj] = type##_Info(); \
135 } \
Lingfeng Yangdef88ba2018-12-13 12:43:17 -0800136
137#define HANDLE_UNREGISTER_IMPL_IMPL(type) \
Lingfeng Yang6ab1b0d2018-11-27 23:36:03 -0800138 void unregister_##type(type obj) { \
139 AutoLock lock(mLock); \
140 info_##type.erase(obj); \
141 } \
142
143 GOLDFISH_VK_LIST_HANDLE_TYPES(HANDLE_REGISTER_IMPL_IMPL)
Lingfeng Yangdef88ba2018-12-13 12:43:17 -0800144 GOLDFISH_VK_LIST_TRIVIAL_HANDLE_TYPES(HANDLE_UNREGISTER_IMPL_IMPL)
145
146 void unregister_VkDevice(VkDevice device) {
147 AutoLock lock(mLock);
148 info_VkDevice.erase(device);
149 }
150
151 void unregister_VkDeviceMemory(VkDeviceMemory mem) {
152 AutoLock lock(mLock);
Lingfeng Yang236abc92018-12-21 20:19:33 -0800153
Lingfeng Yangdef88ba2018-12-13 12:43:17 -0800154 auto it = info_VkDeviceMemory.find(mem);
155 if (it == info_VkDeviceMemory.end()) return;
156
157 auto& memInfo = it->second;
Lingfeng Yang236abc92018-12-21 20:19:33 -0800158
159 if (memInfo.mappedPtr && !memInfo.directMapped) {
Lingfeng Yangdef88ba2018-12-13 12:43:17 -0800160 aligned_buf_free(memInfo.mappedPtr);
161 }
Lingfeng Yang236abc92018-12-21 20:19:33 -0800162
163 // Direct mapping is erased by GoldfishAddressSpaceBlock's
164 // dtor
165 info_VkDeviceMemory.erase(mem);
Lingfeng Yangdef88ba2018-12-13 12:43:17 -0800166 }
Lingfeng Yang6ab1b0d2018-11-27 23:36:03 -0800167
168 void setDeviceInfo(VkDevice device,
169 VkPhysicalDevice physdev,
170 VkPhysicalDeviceProperties props,
171 VkPhysicalDeviceMemoryProperties memProps) {
172 AutoLock lock(mLock);
173 auto& info = info_VkDevice[device];
174 info.physdev = physdev;
175 info.props = props;
176 info.memProps = memProps;
Lingfeng Yang58b89c82018-12-25 11:23:21 -0800177 initHostVisibleMemoryVirtualizationInfo(
Lingfeng Yangafe29d32018-12-25 13:01:52 -0800178 physdev, &memProps,
179 mFeatureInfo->hasDirectMem,
180 &mHostVisibleMemoryVirtInfo);
Lingfeng Yang6ab1b0d2018-11-27 23:36:03 -0800181 }
182
Lingfeng Yang58b89c82018-12-25 11:23:21 -0800183 void setDeviceMemoryInfo(VkDevice device,
184 VkDeviceMemory memory,
Lingfeng Yangdef88ba2018-12-13 12:43:17 -0800185 VkDeviceSize allocationSize,
186 VkDeviceSize mappedSize,
187 uint8_t* ptr,
188 uint32_t memoryTypeIndex) {
189 AutoLock lock(mLock);
Lingfeng Yang58b89c82018-12-25 11:23:21 -0800190 auto& deviceInfo = info_VkDevice[device];
Lingfeng Yangdef88ba2018-12-13 12:43:17 -0800191 auto& info = info_VkDeviceMemory[memory];
Lingfeng Yang58b89c82018-12-25 11:23:21 -0800192
Lingfeng Yangdef88ba2018-12-13 12:43:17 -0800193 info.allocationSize = allocationSize;
194 info.mappedSize = mappedSize;
195 info.mappedPtr = ptr;
196 info.memoryTypeIndex = memoryTypeIndex;
197 }
198
Lingfeng Yang6ab1b0d2018-11-27 23:36:03 -0800199 bool isMemoryTypeHostVisible(VkDevice device, uint32_t typeIndex) const {
200 AutoLock lock(mLock);
201 const auto it = info_VkDevice.find(device);
202
203 if (it == info_VkDevice.end()) return false;
204
205 const auto& info = it->second;
Lingfeng Yangdef88ba2018-12-13 12:43:17 -0800206 return info.memProps.memoryTypes[typeIndex].propertyFlags &
Lingfeng Yang6ab1b0d2018-11-27 23:36:03 -0800207 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
208 }
209
Lingfeng Yangdef88ba2018-12-13 12:43:17 -0800210 uint8_t* getMappedPointer(VkDeviceMemory memory) {
211 AutoLock lock(mLock);
212 const auto it = info_VkDeviceMemory.find(memory);
213 if (it == info_VkDeviceMemory.end()) return nullptr;
214
215 const auto& info = it->second;
216 return info.mappedPtr;
217 }
218
219 VkDeviceSize getMappedSize(VkDeviceMemory memory) {
220 AutoLock lock(mLock);
221 const auto it = info_VkDeviceMemory.find(memory);
222 if (it == info_VkDeviceMemory.end()) return 0;
223
224 const auto& info = it->second;
225 return info.mappedSize;
226 }
227
Lingfeng Yang6ab1b0d2018-11-27 23:36:03 -0800228 VkDeviceSize getNonCoherentExtendedSize(VkDevice device, VkDeviceSize basicSize) const {
229 AutoLock lock(mLock);
230 const auto it = info_VkDevice.find(device);
231 if (it == info_VkDevice.end()) return basicSize;
232 const auto& info = it->second;
233
234 VkDeviceSize nonCoherentAtomSize =
235 info.props.limits.nonCoherentAtomSize;
236 VkDeviceSize atoms =
237 (basicSize + nonCoherentAtomSize - 1) / nonCoherentAtomSize;
238 return atoms * nonCoherentAtomSize;
239 }
240
Lingfeng Yangdef88ba2018-12-13 12:43:17 -0800241 bool isValidMemoryRange(const VkMappedMemoryRange& range) const {
242 AutoLock lock(mLock);
243 const auto it = info_VkDeviceMemory.find(range.memory);
244 if (it == info_VkDeviceMemory.end()) return false;
245 const auto& info = it->second;
246
247 if (!info.mappedPtr) return false;
248
249 VkDeviceSize offset = range.offset;
250 VkDeviceSize size = range.size;
251
252 if (size == VK_WHOLE_SIZE) {
253 return offset <= info.mappedSize;
254 }
255
256 return offset + size <= info.mappedSize;
257 }
258
Lingfeng Yang31754632018-12-21 18:24:55 -0800259 void setupFeatures(const EmulatorFeatureInfo* features) {
260 if (!features || mFeatureInfo) return;
261 mFeatureInfo.reset(new EmulatorFeatureInfo);
262 *mFeatureInfo = *features;
Lingfeng Yang236abc92018-12-21 20:19:33 -0800263
264 if (mFeatureInfo->hasDirectMem) {
265 mGoldfishAddressSpaceBlockProvider.reset(
266 new GoldfishAddressSpaceBlockProvider);
267 }
268 }
269
270 bool usingDirectMapping() const {
Lingfeng Yangafe29d32018-12-25 13:01:52 -0800271 return mHostVisibleMemoryVirtInfo.virtualizationSupported;
Lingfeng Yang31754632018-12-21 18:24:55 -0800272 }
273
Lingfeng Yang97a06702018-12-24 17:02:43 -0800274 void deviceMemoryTransform_tohost(
275 VkDeviceMemory* memory, uint32_t memoryCount,
276 VkDeviceSize* offset, uint32_t offsetCount,
277 VkDeviceSize* size, uint32_t sizeCount,
278 uint32_t* typeIndex, uint32_t typeIndexCount,
279 uint32_t* typeBits, uint32_t typeBitsCount) {
Lingfeng Yangafe29d32018-12-25 13:01:52 -0800280
281 (void)memoryCount;
282 (void)offsetCount;
283 (void)sizeCount;
Lingfeng Yangdf173132018-12-25 13:30:57 -0800284 const auto& hostVirt =
285 mHostVisibleMemoryVirtInfo;
286
287 if (!hostVirt.virtualizationSupported) return;
Lingfeng Yang97a06702018-12-24 17:02:43 -0800288
289 for (uint32_t i = 0; i < memoryCount; ++i) {
290 // TODO
291 (void)memory;
292 (void)offset;
293 (void)size;
294 }
295
296 for (uint32_t i = 0; i < typeIndexCount; ++i) {
Lingfeng Yangdf173132018-12-25 13:30:57 -0800297 typeIndex[i] =
298 hostVirt.memoryTypeIndexMappingToHost[typeIndex[i]];
Lingfeng Yang97a06702018-12-24 17:02:43 -0800299 }
300
301 for (uint32_t i = 0; i < typeBitsCount; ++i) {
Lingfeng Yangdf173132018-12-25 13:30:57 -0800302 uint32_t bits = 0;
303 for (uint32_t j = 0; j < VK_MAX_MEMORY_TYPES; ++j) {
304 bool guestHas = typeBits[i] & (1 << j);
305 uint32_t hostIndex =
306 hostVirt.memoryTypeIndexMappingToHost[j];
307 bits |= guestHas ? (1 << hostIndex) : 0;
308 }
309 typeBits[i] = bits;
Lingfeng Yang97a06702018-12-24 17:02:43 -0800310 }
311 }
312
313 void deviceMemoryTransform_fromhost(
Lingfeng Yang62b23322018-12-24 12:45:47 -0800314 VkDeviceMemory* memory, uint32_t memoryCount,
315 VkDeviceSize* offset, uint32_t offsetCount,
316 VkDeviceSize* size, uint32_t sizeCount,
317 uint32_t* typeIndex, uint32_t typeIndexCount,
318 uint32_t* typeBits, uint32_t typeBitsCount) {
Lingfeng Yang62b23322018-12-24 12:45:47 -0800319
Lingfeng Yangafe29d32018-12-25 13:01:52 -0800320 (void)memoryCount;
321 (void)offsetCount;
322 (void)sizeCount;
323
Lingfeng Yangdf173132018-12-25 13:30:57 -0800324 const auto& hostVirt =
325 mHostVisibleMemoryVirtInfo;
326
327 if (!hostVirt.virtualizationSupported) return;
328
Lingfeng Yang62b23322018-12-24 12:45:47 -0800329 for (uint32_t i = 0; i < memoryCount; ++i) {
330 // TODO
331 (void)memory;
332 (void)offset;
333 (void)size;
334 }
335
336 for (uint32_t i = 0; i < typeIndexCount; ++i) {
Lingfeng Yangdf173132018-12-25 13:30:57 -0800337 typeIndex[i] =
338 hostVirt.memoryTypeIndexMappingFromHost[typeIndex[i]];
Lingfeng Yang62b23322018-12-24 12:45:47 -0800339 }
340
341 for (uint32_t i = 0; i < typeBitsCount; ++i) {
Lingfeng Yangdf173132018-12-25 13:30:57 -0800342 uint32_t bits = 0;
343 for (uint32_t j = 0; j < VK_MAX_MEMORY_TYPES; ++j) {
344 bool hostHas = typeBits[i] & (1 << j);
345 uint32_t guestIndex =
346 hostVirt.memoryTypeIndexMappingFromHost[j];
347 bits |= hostHas ? (1 << guestIndex) : 0;
348
349 if (hostVirt.memoryTypeBitsShouldAdvertiseBoth[j]) {
350 bits |= hostHas ? (1 << j) : 0;
351 }
352 }
353 typeBits[i] = bits;
Lingfeng Yang62b23322018-12-24 12:45:47 -0800354 }
355 }
356
Lingfeng Yangdef88ba2018-12-13 12:43:17 -0800357 VkResult on_vkEnumerateInstanceVersion(
358 void*,
359 VkResult,
360 uint32_t* apiVersion) {
361 if (apiVersion) {
362 *apiVersion = VK_MAKE_VERSION(1, 0, 0);
363 }
364 return VK_SUCCESS;
365 }
366
367 VkResult on_vkEnumerateDeviceExtensionProperties(
368 void*,
369 VkResult,
370 VkPhysicalDevice,
371 const char*,
372 uint32_t* pPropertyCount,
373 VkExtensionProperties*) {
374 *pPropertyCount = 0;
375 return VK_SUCCESS;
376 }
377
378 void on_vkGetPhysicalDeviceProperties2(
379 void*,
380 VkPhysicalDevice,
381 VkPhysicalDeviceProperties2*) {
382 // no-op
383 }
384
Lingfeng Yang97a06702018-12-24 17:02:43 -0800385 void on_vkGetPhysicalDeviceMemoryProperties(
386 void*,
Lingfeng Yangdf173132018-12-25 13:30:57 -0800387 VkPhysicalDevice physdev,
388 VkPhysicalDeviceMemoryProperties* out) {
389
390 initHostVisibleMemoryVirtualizationInfo(
391 physdev,
392 out,
393 mFeatureInfo->hasDirectMem,
394 &mHostVisibleMemoryVirtInfo);
395
396 if (mHostVisibleMemoryVirtInfo.virtualizationSupported) {
397 *out = mHostVisibleMemoryVirtInfo.guestMemoryProperties;
398 }
399 }
Lingfeng Yang97a06702018-12-24 17:02:43 -0800400
Lingfeng Yang131d5a42018-11-30 12:00:33 -0800401 VkResult on_vkCreateDevice(
402 void* context,
403 VkResult input_result,
404 VkPhysicalDevice physicalDevice,
405 const VkDeviceCreateInfo*,
406 const VkAllocationCallbacks*,
407 VkDevice* pDevice) {
408
409 if (input_result != VK_SUCCESS) return input_result;
410
411 VkEncoder* enc = (VkEncoder*)context;
412
413 VkPhysicalDeviceProperties props;
414 VkPhysicalDeviceMemoryProperties memProps;
415 enc->vkGetPhysicalDeviceProperties(physicalDevice, &props);
416 enc->vkGetPhysicalDeviceMemoryProperties(physicalDevice, &memProps);
417
418 setDeviceInfo(*pDevice, physicalDevice, props, memProps);
419
420 return input_result;
421 }
422
423 VkResult on_vkAllocateMemory(
Lingfeng Yang236abc92018-12-21 20:19:33 -0800424 void* context,
Lingfeng Yang131d5a42018-11-30 12:00:33 -0800425 VkResult input_result,
426 VkDevice device,
427 const VkMemoryAllocateInfo* pAllocateInfo,
428 const VkAllocationCallbacks*,
429 VkDeviceMemory* pMemory) {
430
431 if (input_result != VK_SUCCESS) return input_result;
432
Lingfeng Yangdef88ba2018-12-13 12:43:17 -0800433 VkDeviceSize allocationSize = pAllocateInfo->allocationSize;
434 VkDeviceSize mappedSize = getNonCoherentExtendedSize(device, allocationSize);
435 uint8_t* mappedPtr = nullptr;
Lingfeng Yang236abc92018-12-21 20:19:33 -0800436 bool hostVisible =
437 isMemoryTypeHostVisible(device, pAllocateInfo->memoryTypeIndex);
Lingfeng Yangafe29d32018-12-25 13:01:52 -0800438 bool directMappingSupported = usingDirectMapping();
439 if (hostVisible && !directMappingSupported) {
Lingfeng Yangdef88ba2018-12-13 12:43:17 -0800440 mappedPtr = (uint8_t*)aligned_buf_alloc(4096, mappedSize);
Lingfeng Yang236abc92018-12-21 20:19:33 -0800441 D("host visible alloc (non-direct): "
442 "size 0x%llx host ptr %p mapped size 0x%llx",
443 (unsigned long long)allocationSize, mappedPtr,
444 (unsigned long long)mappedSize);
Lingfeng Yang131d5a42018-11-30 12:00:33 -0800445 }
446
Lingfeng Yangdef88ba2018-12-13 12:43:17 -0800447 setDeviceMemoryInfo(
Lingfeng Yang58b89c82018-12-25 11:23:21 -0800448 device, *pMemory, allocationSize, mappedSize, mappedPtr,
Lingfeng Yangdef88ba2018-12-13 12:43:17 -0800449 pAllocateInfo->memoryTypeIndex);
Lingfeng Yang131d5a42018-11-30 12:00:33 -0800450
Lingfeng Yang236abc92018-12-21 20:19:33 -0800451 bool doDirectMap =
Lingfeng Yangafe29d32018-12-25 13:01:52 -0800452 hostVisible && directMappingSupported;
Lingfeng Yang236abc92018-12-21 20:19:33 -0800453
454 if (doDirectMap) {
455 VkEncoder* enc = (VkEncoder*)context;
456
457 uint64_t directMappedAddr = 0;
458
459 VkResult directMapResult =
460 enc->vkMapMemoryIntoAddressSpaceGOOGLE(
461 device, *pMemory, &directMappedAddr);
462
463 if (directMapResult != VK_SUCCESS) {
464 return directMapResult;
465 }
466
467 AutoLock lock(mLock);
468
469 auto it = info_VkDeviceMemory.find(*pMemory);
470 if (it == info_VkDeviceMemory.end()) {
471 return VK_ERROR_INITIALIZATION_FAILED;
472 }
473
474 auto& info = it->second;
475 info.mappedPtr = (uint8_t*)(uintptr_t)directMappedAddr;
476 info.directMapped = true;
477
478 D("host visible alloc (direct): "
479 "size 0x%llx host ptr %p mapped size 0x%llx",
480 (unsigned long long)allocationSize, info.mappedPtr,
481 (unsigned long long)mappedSize);
482 }
483
Lingfeng Yang131d5a42018-11-30 12:00:33 -0800484 return input_result;
485 }
486
Lingfeng Yangdef88ba2018-12-13 12:43:17 -0800487 VkResult on_vkMapMemory(
488 void*,
489 VkResult host_result,
490 VkDevice,
491 VkDeviceMemory memory,
492 VkDeviceSize offset,
493 VkDeviceSize size,
494 VkMemoryMapFlags,
495 void** ppData) {
496
497 if (host_result != VK_SUCCESS) return host_result;
498
499 AutoLock lock(mLock);
500
501 auto it = info_VkDeviceMemory.find(memory);
502 if (it == info_VkDeviceMemory.end()) return VK_ERROR_MEMORY_MAP_FAILED;
503
504 auto& info = it->second;
505
506 if (!info.mappedPtr) return VK_ERROR_MEMORY_MAP_FAILED;
507
508 if (size != VK_WHOLE_SIZE &&
509 (info.mappedPtr + offset + size > info.mappedPtr + info.allocationSize)) {
510 return VK_ERROR_MEMORY_MAP_FAILED;
511 }
512
513 *ppData = info.mappedPtr + offset;
514
515 return host_result;
516 }
517
518 void on_vkUnmapMemory(
519 void*,
520 VkDevice,
521 VkDeviceMemory) {
522 // no-op
523 }
524
525 void unwrap_VkNativeBufferANDROID(
526 const VkImageCreateInfo* pCreateInfo,
527 VkImageCreateInfo* local_pCreateInfo) {
528
529 if (!pCreateInfo->pNext) return;
530
531 const VkNativeBufferANDROID* nativeInfo =
532 reinterpret_cast<const VkNativeBufferANDROID*>(pCreateInfo->pNext);
533
534 if (VK_STRUCTURE_TYPE_NATIVE_BUFFER_ANDROID != nativeInfo->sType) {
535 return;
536 }
537
538 const cb_handle_t* cb_handle =
539 reinterpret_cast<const cb_handle_t*>(nativeInfo->handle);
540
541 if (!cb_handle) return;
542
543 VkNativeBufferANDROID* nativeInfoOut =
Lingfeng Yange637ca52018-12-14 18:24:56 -0800544 reinterpret_cast<VkNativeBufferANDROID*>(
545 const_cast<void*>(
546 local_pCreateInfo->pNext));
Lingfeng Yangdef88ba2018-12-13 12:43:17 -0800547
548 if (!nativeInfoOut->handle) {
549 ALOGE("FATAL: Local native buffer info not properly allocated!");
550 abort();
551 }
552
553 *(uint32_t*)(nativeInfoOut->handle) = cb_handle->hostHandle;
554 }
555
556 void unwrap_vkAcquireImageANDROID_nativeFenceFd(int fd, int*) {
557 if (fd != -1) {
558 sync_wait(fd, 3000);
559 }
560 }
561
Lingfeng Yang236abc92018-12-21 20:19:33 -0800562 // Action of vkMapMemoryIntoAddressSpaceGOOGLE:
563 // 1. preprocess (on_vkMapMemoryIntoAddressSpaceGOOGLE_pre):
564 // uses address space device to reserve the right size of
565 // memory.
566 // 2. the reservation results in a physical address. the physical
567 // address is set as |*pAddress|.
568 // 3. after pre, the API call is encoded to the host, where the
569 // value of pAddress is also sent (the physical address).
570 // 4. the host will obtain the actual gpu pointer and send it
571 // back out in |*pAddress|.
572 // 5. postprocess (on_vkMapMemoryIntoAddressSpaceGOOGLE) will run,
573 // using the mmap() method of GoldfishAddressSpaceBlock to obtain
574 // a pointer in guest userspace corresponding to the host pointer.
575 VkResult on_vkMapMemoryIntoAddressSpaceGOOGLE_pre(
576 void*,
577 VkResult,
578 VkDevice,
579 VkDeviceMemory memory,
580 uint64_t* pAddress) {
581
582 AutoLock lock(mLock);
583
584 auto it = info_VkDeviceMemory.find(memory);
585 if (it == info_VkDeviceMemory.end()) {
586 return VK_ERROR_OUT_OF_HOST_MEMORY;
587 }
588
589 auto& memInfo = it->second;
590 memInfo.goldfishAddressSpaceBlock.reset(
591 new GoldfishAddressSpaceBlock);
592 auto& block = *(memInfo.goldfishAddressSpaceBlock);
593
594 block.allocate(
595 mGoldfishAddressSpaceBlockProvider.get(),
596 memInfo.mappedSize);
597
598 *pAddress = block.physAddr();
599
600 return VK_SUCCESS;
601 }
602
603 VkResult on_vkMapMemoryIntoAddressSpaceGOOGLE(
604 void*,
605 VkResult input_result,
606 VkDevice,
607 VkDeviceMemory memory,
608 uint64_t* pAddress) {
609
610 if (input_result != VK_SUCCESS) {
611 return input_result;
612 }
613
614 // Now pAddress points to the gpu addr from host.
615 AutoLock lock(mLock);
616
617 auto it = info_VkDeviceMemory.find(memory);
618 if (it == info_VkDeviceMemory.end()) {
619 return VK_ERROR_OUT_OF_HOST_MEMORY;
620 }
621
622 auto& memInfo = it->second;
623 auto& block = *(memInfo.goldfishAddressSpaceBlock);
624
625 uint64_t gpuAddr = *pAddress;
626
627 void* userPtr = block.mmap(gpuAddr);
628
629 *pAddress = (uint64_t)(uintptr_t)userPtr;
630
631 return input_result;
632 }
633
Lingfeng Yang6ab1b0d2018-11-27 23:36:03 -0800634private:
635 mutable Lock mLock;
Lingfeng Yangafe29d32018-12-25 13:01:52 -0800636 HostVisibleMemoryVirtualizationInfo mHostVisibleMemoryVirtInfo;
Lingfeng Yang31754632018-12-21 18:24:55 -0800637 std::unique_ptr<EmulatorFeatureInfo> mFeatureInfo;
Lingfeng Yang236abc92018-12-21 20:19:33 -0800638 std::unique_ptr<GoldfishAddressSpaceBlockProvider> mGoldfishAddressSpaceBlockProvider;
Lingfeng Yang71b596b2018-11-07 18:03:25 -0800639};
Lingfeng Yang71b596b2018-11-07 18:03:25 -0800640ResourceTracker::ResourceTracker() : mImpl(new ResourceTracker::Impl()) { }
641ResourceTracker::~ResourceTracker() { }
Lingfeng Yang71b596b2018-11-07 18:03:25 -0800642VulkanHandleMapping* ResourceTracker::createMapping() {
643 return &mImpl->createMapping;
644}
Lingfeng Yang71b596b2018-11-07 18:03:25 -0800645VulkanHandleMapping* ResourceTracker::unwrapMapping() {
646 return &mImpl->unwrapMapping;
647}
Lingfeng Yang71b596b2018-11-07 18:03:25 -0800648VulkanHandleMapping* ResourceTracker::destroyMapping() {
649 return &mImpl->destroyMapping;
650}
Lingfeng Yang2285df12018-11-17 16:25:11 -0800651VulkanHandleMapping* ResourceTracker::defaultMapping() {
652 return &mImpl->defaultMapping;
653}
Lingfeng Yang71b596b2018-11-07 18:03:25 -0800654static ResourceTracker* sTracker = nullptr;
Lingfeng Yang71b596b2018-11-07 18:03:25 -0800655// static
656ResourceTracker* ResourceTracker::get() {
657 if (!sTracker) {
658 // To be initialized once on vulkan device open.
659 sTracker = new ResourceTracker;
660 }
661 return sTracker;
662}
Lingfeng Yang71b596b2018-11-07 18:03:25 -0800663
Lingfeng Yang6ab1b0d2018-11-27 23:36:03 -0800664#define HANDLE_REGISTER_IMPL(type) \
665 void ResourceTracker::register_##type(type obj) { \
666 mImpl->register_##type(obj); \
667 } \
668 void ResourceTracker::unregister_##type(type obj) { \
669 mImpl->unregister_##type(obj); \
670 } \
671
672GOLDFISH_VK_LIST_HANDLE_TYPES(HANDLE_REGISTER_IMPL)
673
674void ResourceTracker::setDeviceInfo(
675 VkDevice device,
676 VkPhysicalDevice physdev,
677 VkPhysicalDeviceProperties props,
678 VkPhysicalDeviceMemoryProperties memProps) {
679 mImpl->setDeviceInfo(device, physdev, props, memProps);
680}
681
682bool ResourceTracker::isMemoryTypeHostVisible(
683 VkDevice device, uint32_t typeIndex) const {
684 return mImpl->isMemoryTypeHostVisible(device, typeIndex);
685}
686
Lingfeng Yangdef88ba2018-12-13 12:43:17 -0800687uint8_t* ResourceTracker::getMappedPointer(VkDeviceMemory memory) {
688 return mImpl->getMappedPointer(memory);
689}
690
691VkDeviceSize ResourceTracker::getMappedSize(VkDeviceMemory memory) {
692 return mImpl->getMappedSize(memory);
693}
694
Lingfeng Yang6ab1b0d2018-11-27 23:36:03 -0800695VkDeviceSize ResourceTracker::getNonCoherentExtendedSize(VkDevice device, VkDeviceSize basicSize) const {
696 return mImpl->getNonCoherentExtendedSize(device, basicSize);
697}
698
Lingfeng Yangdef88ba2018-12-13 12:43:17 -0800699bool ResourceTracker::isValidMemoryRange(const VkMappedMemoryRange& range) const {
700 return mImpl->isValidMemoryRange(range);
701}
702
Lingfeng Yang31754632018-12-21 18:24:55 -0800703void ResourceTracker::setupFeatures(const EmulatorFeatureInfo* features) {
704 mImpl->setupFeatures(features);
705}
706
Lingfeng Yang236abc92018-12-21 20:19:33 -0800707bool ResourceTracker::usingDirectMapping() const {
708 return mImpl->usingDirectMapping();
709}
710
Lingfeng Yang97a06702018-12-24 17:02:43 -0800711void ResourceTracker::deviceMemoryTransform_tohost(
Lingfeng Yang62b23322018-12-24 12:45:47 -0800712 VkDeviceMemory* memory, uint32_t memoryCount,
713 VkDeviceSize* offset, uint32_t offsetCount,
714 VkDeviceSize* size, uint32_t sizeCount,
715 uint32_t* typeIndex, uint32_t typeIndexCount,
716 uint32_t* typeBits, uint32_t typeBitsCount) {
Lingfeng Yang97a06702018-12-24 17:02:43 -0800717 mImpl->deviceMemoryTransform_tohost(
718 memory, memoryCount,
719 offset, offsetCount,
720 size, sizeCount,
721 typeIndex, typeIndexCount,
722 typeBits, typeBitsCount);
723}
724
725void ResourceTracker::deviceMemoryTransform_fromhost(
726 VkDeviceMemory* memory, uint32_t memoryCount,
727 VkDeviceSize* offset, uint32_t offsetCount,
728 VkDeviceSize* size, uint32_t sizeCount,
729 uint32_t* typeIndex, uint32_t typeIndexCount,
730 uint32_t* typeBits, uint32_t typeBitsCount) {
731 mImpl->deviceMemoryTransform_fromhost(
Lingfeng Yang62b23322018-12-24 12:45:47 -0800732 memory, memoryCount,
733 offset, offsetCount,
734 size, sizeCount,
735 typeIndex, typeIndexCount,
736 typeBits, typeBitsCount);
737}
738
Lingfeng Yangdef88ba2018-12-13 12:43:17 -0800739VkResult ResourceTracker::on_vkEnumerateInstanceVersion(
740 void* context,
741 VkResult input_result,
742 uint32_t* apiVersion) {
743 return mImpl->on_vkEnumerateInstanceVersion(context, input_result, apiVersion);
744}
745
746VkResult ResourceTracker::on_vkEnumerateDeviceExtensionProperties(
747 void* context,
748 VkResult input_result,
749 VkPhysicalDevice physicalDevice,
750 const char* pLayerName,
751 uint32_t* pPropertyCount,
752 VkExtensionProperties* pProperties) {
753 return mImpl->on_vkEnumerateDeviceExtensionProperties(
754 context, input_result, physicalDevice, pLayerName, pPropertyCount, pProperties);
755}
756
757void ResourceTracker::on_vkGetPhysicalDeviceProperties2(
758 void* context,
759 VkPhysicalDevice physicalDevice,
760 VkPhysicalDeviceProperties2* pProperties) {
761 mImpl->on_vkGetPhysicalDeviceProperties2(context, physicalDevice, pProperties);
762}
763
Lingfeng Yang97a06702018-12-24 17:02:43 -0800764void ResourceTracker::on_vkGetPhysicalDeviceMemoryProperties(
765 void* context,
766 VkPhysicalDevice physicalDevice,
767 VkPhysicalDeviceMemoryProperties* pMemoryProperties) {
768 mImpl->on_vkGetPhysicalDeviceMemoryProperties(
769 context, physicalDevice, pMemoryProperties);
770}
771
Lingfeng Yang131d5a42018-11-30 12:00:33 -0800772VkResult ResourceTracker::on_vkCreateDevice(
773 void* context,
774 VkResult input_result,
775 VkPhysicalDevice physicalDevice,
776 const VkDeviceCreateInfo* pCreateInfo,
777 const VkAllocationCallbacks* pAllocator,
778 VkDevice* pDevice) {
779 return mImpl->on_vkCreateDevice(
780 context, input_result, physicalDevice, pCreateInfo, pAllocator, pDevice);
781}
782
783VkResult ResourceTracker::on_vkAllocateMemory(
784 void* context,
785 VkResult input_result,
786 VkDevice device,
787 const VkMemoryAllocateInfo* pAllocateInfo,
788 const VkAllocationCallbacks* pAllocator,
789 VkDeviceMemory* pMemory) {
790 return mImpl->on_vkAllocateMemory(
791 context, input_result, device, pAllocateInfo, pAllocator, pMemory);
792}
793
Lingfeng Yangdef88ba2018-12-13 12:43:17 -0800794VkResult ResourceTracker::on_vkMapMemory(
795 void* context,
796 VkResult input_result,
797 VkDevice device,
798 VkDeviceMemory memory,
799 VkDeviceSize offset,
800 VkDeviceSize size,
801 VkMemoryMapFlags flags,
802 void** ppData) {
803 return mImpl->on_vkMapMemory(
804 context, input_result, device, memory, offset, size, flags, ppData);
805}
806
807void ResourceTracker::on_vkUnmapMemory(
808 void* context,
809 VkDevice device,
810 VkDeviceMemory memory) {
811 mImpl->on_vkUnmapMemory(context, device, memory);
812}
813
814void ResourceTracker::unwrap_VkNativeBufferANDROID(
815 const VkImageCreateInfo* pCreateInfo,
816 VkImageCreateInfo* local_pCreateInfo) {
817 mImpl->unwrap_VkNativeBufferANDROID(pCreateInfo, local_pCreateInfo);
818}
819
820void ResourceTracker::unwrap_vkAcquireImageANDROID_nativeFenceFd(int fd, int* fd_out) {
821 mImpl->unwrap_vkAcquireImageANDROID_nativeFenceFd(fd, fd_out);
822}
823
Lingfeng Yang236abc92018-12-21 20:19:33 -0800824VkResult ResourceTracker::on_vkMapMemoryIntoAddressSpaceGOOGLE_pre(
825 void* context,
826 VkResult input_result,
827 VkDevice device,
828 VkDeviceMemory memory,
829 uint64_t* pAddress) {
830 return mImpl->on_vkMapMemoryIntoAddressSpaceGOOGLE_pre(
831 context, input_result, device, memory, pAddress);
832}
833
834VkResult ResourceTracker::on_vkMapMemoryIntoAddressSpaceGOOGLE(
835 void* context,
836 VkResult input_result,
837 VkDevice device,
838 VkDeviceMemory memory,
839 uint64_t* pAddress) {
840 return mImpl->on_vkMapMemoryIntoAddressSpaceGOOGLE(
841 context, input_result, device, memory, pAddress);
842}
843
Lingfeng Yang71b596b2018-11-07 18:03:25 -0800844} // namespace goldfish_vk