struct vn_device_memory *mem,
const VkMemoryAllocateInfo *alloc_info,
const VkAllocationCallbacks *alloc,
- struct AHardwareBuffer *ahb)
+ struct AHardwareBuffer *ahb,
+ bool internal_ahb)
{
VkDevice device = vn_device_to_handle(dev);
const VkMemoryDedicatedAllocateInfo *dedicated_info =
int dup_fd = -1;
uint64_t alloc_size = 0;
uint32_t mem_type_bits = 0;
+ uint32_t mem_type_index = alloc_info->memoryTypeIndex;
bool force_unmappable = false;
VkResult result = VK_SUCCESS;
if (result != VK_SUCCESS)
return result;
- if (((1 << alloc_info->memoryTypeIndex) & mem_type_bits) == 0) {
- vn_log(dev->instance, "memoryTypeIndex(%u) mem_type_bits(0x%X)",
- alloc_info->memoryTypeIndex, mem_type_bits);
- return VK_ERROR_INVALID_EXTERNAL_HANDLE;
- }
-
/* If ahb is for an image, finish the deferred image creation first */
if (dedicated_info && dedicated_info->image != VK_NULL_HANDLE) {
struct vn_image *img = vn_image_from_handle(dedicated_info->image);
alloc_size = mem_req.size;
+ /* XXX Workaround before spec issue #2762 gets resolved. If importing an
+ * internally allocated AHB from the exportable path, memoryTypeIndex is
+ * undefined while defaulting to zero, which can be incompatible with
+ * the queried memoryTypeBits from the combined memory requirement and
+ * dma_buf fd properties. Thus we override the requested memoryTypeIndex
+ * to an applicable one if existed.
+ */
+ if (internal_ahb) {
+ if ((mem_type_bits & mem_req.memoryTypeBits) == 0) {
+ vn_log(dev->instance, "memoryTypeBits: img(0x%X) fd(0x%X)",
+ mem_req.memoryTypeBits, mem_type_bits);
+ return VK_ERROR_INVALID_EXTERNAL_HANDLE;
+ }
+
+ mem_type_index = ffs(mem_type_bits & mem_req.memoryTypeBits) - 1;
+ }
+
/* XXX Workaround before we use cross-domain backend in minigbm. The
* blob_mem allocated from virgl backend can have a queried guest mappable
* size smaller than the size returned from image memory requirement.
}
alloc_size = mem_req.size;
+
+ assert((1 << mem_type_index) & mem_req.memoryTypeBits);
}
+ assert((1 << mem_type_index) & mem_type_bits);
+
errno = 0;
dup_fd = os_dupfd_cloexec(dma_buf_fd);
if (dup_fd < 0)
.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
.pNext = dedicated_info,
.allocationSize = alloc_size,
- .memoryTypeIndex = alloc_info->memoryTypeIndex,
+ .memoryTypeIndex = mem_type_index,
};
result = vn_device_memory_import_dma_buf(dev, mem, &local_alloc_info,
force_unmappable, dup_fd);
return VK_ERROR_OUT_OF_HOST_MEMORY;
VkResult result =
- vn_android_device_import_ahb(dev, mem, alloc_info, alloc, ahb);
+ vn_android_device_import_ahb(dev, mem, alloc_info, alloc, ahb, true);
/* ahb alloc has already acquired a ref and import will acquire another,
* must release one here to avoid leak.
struct vn_device_memory *mem,
const VkMemoryAllocateInfo *alloc_info,
const VkAllocationCallbacks *alloc,
- struct AHardwareBuffer *ahb);
+ struct AHardwareBuffer *ahb,
+ bool internal_ahb);
VkResult
vn_android_device_allocate_ahb(struct vn_device *dev,
UNUSED struct vn_device_memory *mem,
UNUSED const VkMemoryAllocateInfo *alloc_info,
UNUSED const VkAllocationCallbacks *alloc,
- UNUSED struct AHardwareBuffer *ahb)
+ UNUSED struct AHardwareBuffer *ahb,
+ UNUSED bool internal_ahb)
{
return VK_ERROR_OUT_OF_HOST_MEMORY;
}