Skip to content

Commit 5f3374d

Browse files
committed
[10/n][ET-VK] Introduce create_image_from_ahb utility
Pull Request resolved: #5992 We now include handle to `VkDevice` in `VulkanImage` since our allocations don't go through VMA. **Internal:** Following image creation of `myvulkanahb`. https://www.internalfb.com/code/aosp-vendor-meta-tools-camera-tools/[wrist-sw5100-14.0%3Af8460689765eee9332f461491a1edcfc6ad8fb92]/myvulkanahb/myvulkanahb.cpp?lines=22%2C94-96 https://www.internalfb.com/code/aosp-vendor-meta-tools-camera-tools/[wrist-sw5100-14.0%3Af8460689765eee9332f461491a1edcfc6ad8fb92]/myvulkanahb/vulkan/ImageProcessorAhbRgbaInRgbaOut.cpp?lines=26-36%2C40-47 ghstack-source-id: 244302584 @exported-using-ghexport Differential Revision: [D63298759](https://our.internmc.facebook.com/intern/diff/D63298759/)
1 parent b66c255 commit 5f3374d

File tree

7 files changed

+236
-9
lines changed

7 files changed

+236
-9
lines changed

backends/vulkan/runtime/api/containers/Tensor.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,7 @@ vkapi::VulkanImage allocate_image(
221221
VkSampler sampler = adapter_ptr->sampler_cache().retrieve(sampler_props);
222222

223223
return adapter_ptr->vma().create_image(
224+
context_ptr->device(),
224225
vkapi::create_extent3d(image_extents),
225226
image_format,
226227
image_type,
Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
/*
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
* All rights reserved.
4+
*
5+
* This source code is licensed under the BSD-style license found in the
6+
* LICENSE file in the root directory of this source tree.
7+
*/
8+
9+
#pragma once
10+
11+
// @lint-ignore-every CLANGTIDY facebook-hte-BadMemberName
12+
13+
#include <executorch/backends/vulkan/runtime/api/api.h>
14+
15+
#include <executorch/backends/vulkan/runtime/vk_api/VkUtils.h>
16+
17+
namespace vkcompute {
18+
namespace utils {
19+
namespace {
20+
21+
uint32_t find_mem_type_idx(
22+
api::Context* context,
23+
uint32_t mem_type_bits,
24+
const VkFlags flags) {
25+
VkPhysicalDeviceMemoryProperties mem_props;
26+
vkGetPhysicalDeviceMemoryProperties(
27+
context->adapter_ptr()->physical_handle(), &mem_props);
28+
29+
for (uint32_t i = 0; i < mem_props.memoryTypeCount; ++i) {
30+
if ((mem_type_bits & 1u) &&
31+
(mem_props.memoryTypes[i].propertyFlags & flags) == flags) {
32+
return i;
33+
}
34+
mem_type_bits >>= 1u;
35+
}
36+
VK_THROW("Failed to find memory type index for AHB");
37+
}
38+
39+
VkImage create_image(
40+
api::Context* context,
41+
AHardwareBuffer* ahb,
42+
const VkImageUsageFlags usage) {
43+
AHardwareBuffer_acquire(ahb);
44+
AHardwareBuffer_Desc desc;
45+
AHardwareBuffer_describe(ahb, &desc);
46+
47+
VkAndroidHardwareBufferFormatPropertiesANDROID format_info = {
48+
.sType =
49+
VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_ANDROID,
50+
.pNext = nullptr,
51+
};
52+
53+
VkAndroidHardwareBufferPropertiesANDROID ahb_props = {
54+
.sType = VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_PROPERTIES_ANDROID,
55+
.pNext = &format_info,
56+
};
57+
58+
VK_CHECK(vkGetAndroidHardwareBufferPropertiesANDROID(
59+
context->device(), ahb, &ahb_props));
60+
61+
const VkExternalMemoryImageCreateInfo ext_create_info = {
62+
.sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO,
63+
.pNext = nullptr,
64+
.handleTypes =
65+
VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID,
66+
};
67+
const auto format = VK_FORMAT_R8G8B8A8_UNORM;
68+
const auto tiling = VK_IMAGE_TILING_LINEAR;
69+
const VkImageCreateInfo createInfo = {
70+
.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
71+
.pNext = &ext_create_info,
72+
.flags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT,
73+
.imageType = VK_IMAGE_TYPE_2D,
74+
.format = format,
75+
.extent = {desc.width, desc.height, 1u},
76+
.mipLevels = 1u,
77+
.arrayLayers = 1u,
78+
.samples = VK_SAMPLE_COUNT_1_BIT,
79+
.tiling = tiling,
80+
.usage = usage,
81+
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
82+
.queueFamilyIndexCount = 0,
83+
.pQueueFamilyIndices = nullptr,
84+
.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
85+
};
86+
87+
VkImage image;
88+
VK_CHECK(vkCreateImage(context->device(), &createInfo, nullptr, &image));
89+
90+
const auto flags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
91+
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
92+
VkPhysicalDeviceMemoryProperties mem_props;
93+
vkGetPhysicalDeviceMemoryProperties(
94+
context->adapter_ptr()->physical_handle(), &mem_props);
95+
96+
const auto mem_type_idx =
97+
find_mem_type_idx(context, ahb_props.memoryTypeBits, flags);
98+
99+
const VkImportAndroidHardwareBufferInfoANDROID androidHardwareBufferInfo = {
100+
.sType = VK_STRUCTURE_TYPE_IMPORT_ANDROID_HARDWARE_BUFFER_INFO_ANDROID,
101+
.pNext = nullptr,
102+
.buffer = ahb,
103+
};
104+
const VkMemoryDedicatedAllocateInfo mem_alloc_info = {
105+
.sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO,
106+
.pNext = &androidHardwareBufferInfo,
107+
.image = image,
108+
.buffer = VK_NULL_HANDLE,
109+
};
110+
const VkMemoryAllocateInfo alloc_info = {
111+
.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
112+
.pNext = &mem_alloc_info,
113+
.allocationSize = ahb_props.allocationSize,
114+
.memoryTypeIndex = mem_type_idx,
115+
};
116+
117+
VkDeviceMemory memory;
118+
VK_CHECK(vkAllocateMemory(context->device(), &alloc_info, nullptr, &memory));
119+
VK_CHECK(vkBindImageMemory(context->device(), image, memory, 0));
120+
121+
return image;
122+
}
123+
124+
VkImageView create_image_view(api::Context* context, const VkImage& image) {
125+
const VkImageViewCreateInfo image_view_ci = {
126+
.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
127+
.pNext = nullptr,
128+
.flags = 0,
129+
.image = image,
130+
.viewType = VK_IMAGE_VIEW_TYPE_2D,
131+
.format = VK_FORMAT_R8G8B8A8_UNORM,
132+
.components =
133+
{
134+
VK_COMPONENT_SWIZZLE_IDENTITY,
135+
VK_COMPONENT_SWIZZLE_IDENTITY,
136+
VK_COMPONENT_SWIZZLE_IDENTITY,
137+
VK_COMPONENT_SWIZZLE_IDENTITY,
138+
},
139+
.subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1},
140+
};
141+
142+
VkImageView image_view;
143+
VK_CHECK(vkCreateImageView(
144+
context->device(), &image_view_ci, nullptr, &image_view));
145+
return image_view;
146+
}
147+
148+
VkSampler create_sampler(api::Context* context) {
149+
vkapi::ImageSampler::Properties sampler_props{
150+
VK_FILTER_LINEAR,
151+
VK_SAMPLER_MIPMAP_MODE_LINEAR,
152+
VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
153+
VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE,
154+
};
155+
auto sampler =
156+
context->adapter_ptr()->sampler_cache().retrieve(sampler_props);
157+
return sampler;
158+
}
159+
160+
} // namespace
161+
162+
vkapi::VulkanImage create_image_from_ahb(
163+
api::Context* context,
164+
AHardwareBuffer* ahb,
165+
const uint32_t width,
166+
const uint32_t height,
167+
const VkImageUsageFlags usage) {
168+
const auto image_type = VK_IMAGE_TYPE_2D;
169+
const auto image_format = VK_FORMAT_R8G8B8A8_UNORM;
170+
const utils::uvec3 extents({width, height, 1});
171+
172+
const vkapi::VulkanImage::ImageProperties image_props = {
173+
image_type, image_format, vkapi::create_extent3d(extents), usage};
174+
175+
auto image = create_image(context, ahb, usage);
176+
auto image_view = create_image_view(context, image);
177+
auto sampler = (usage & VK_IMAGE_USAGE_SAMPLED_BIT) ? create_sampler(context)
178+
: VK_NULL_HANDLE;
179+
180+
return vkapi::VulkanImage(
181+
context->device(), image_props, image, image_view, sampler);
182+
}
183+
184+
} // namespace utils
185+
} // namespace vkcompute

backends/vulkan/runtime/vk_api/Descriptor.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,8 +116,12 @@ DescriptorSet& DescriptorSet::bind(
116116
DescriptorSet& DescriptorSet::bind(
117117
const uint32_t idx,
118118
const VulkanImage& image) {
119-
VK_CHECK_COND(
120-
image.has_memory(), "Image must be bound to memory for it to be usable");
119+
// Check is only accurate for images allocated with VMA
120+
if (image.vma_allocator() != VK_NULL_HANDLE) {
121+
VK_CHECK_COND(
122+
image.has_memory(),
123+
"Image must be bound to memory for it to be usable");
124+
}
121125

122126
VkImageLayout binding_layout = image.layout();
123127
if (shader_layout_signature_[idx] == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) {

backends/vulkan/runtime/vk_api/memory/Allocator.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ Allocation Allocator::create_allocation(
9595
}
9696

9797
VulkanImage Allocator::create_image(
98+
const VkDevice device,
9899
const VkExtent3D& extents,
99100
const VkFormat image_format,
100101
const VkImageType image_type,
@@ -127,6 +128,7 @@ VulkanImage Allocator::create_image(
127128
const VkImageLayout initial_layout = VK_IMAGE_LAYOUT_UNDEFINED;
128129

129130
return VulkanImage(
131+
device,
130132
allocator_,
131133
alloc_create_info,
132134
image_props,

backends/vulkan/runtime/vk_api/memory/Allocator.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ class Allocator final {
5555
const VmaAllocationCreateInfo& create_info);
5656

5757
VulkanImage create_image(
58+
const VkDevice,
5859
const VkExtent3D&,
5960
const VkFormat,
6061
const VkImageType,

backends/vulkan/runtime/vk_api/memory/Image.cpp

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,8 @@ void swap(ImageSampler& lhs, ImageSampler& rhs) noexcept {
9292
//
9393

9494
VulkanImage::VulkanImage()
95-
: image_properties_{},
95+
: device_{VK_NULL_HANDLE},
96+
image_properties_{},
9697
view_properties_{},
9798
sampler_properties_{},
9899
allocator_(VK_NULL_HANDLE),
@@ -108,6 +109,7 @@ VulkanImage::VulkanImage()
108109
layout_{} {}
109110

110111
VulkanImage::VulkanImage(
112+
VkDevice device,
111113
VmaAllocator vma_allocator,
112114
const VmaAllocationCreateInfo& allocation_create_info,
113115
const ImageProperties& image_props,
@@ -116,7 +118,8 @@ VulkanImage::VulkanImage(
116118
const VkImageLayout layout,
117119
VkSampler sampler,
118120
const bool allocate_memory)
119-
: image_properties_(image_props),
121+
: device_{device},
122+
image_properties_(image_props),
120123
view_properties_(view_props),
121124
sampler_properties_(sampler_props),
122125
allocator_(vma_allocator),
@@ -178,8 +181,30 @@ VulkanImage::VulkanImage(
178181
}
179182
}
180183

184+
VulkanImage::VulkanImage(
185+
VkDevice device,
186+
const ImageProperties& image_props,
187+
VkImage image,
188+
VkImageView image_view,
189+
VkSampler sampler)
190+
: device_{device},
191+
image_properties_{image_props},
192+
view_properties_{},
193+
sampler_properties_{},
194+
allocator_(VK_NULL_HANDLE),
195+
memory_{},
196+
owns_memory_(false),
197+
is_copy_(false),
198+
handles_{
199+
image,
200+
image_view,
201+
sampler,
202+
},
203+
layout_{VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL} {}
204+
181205
VulkanImage::VulkanImage(const VulkanImage& other) noexcept
182-
: image_properties_(other.image_properties_),
206+
: device_(other.device_),
207+
image_properties_(other.image_properties_),
183208
view_properties_(other.view_properties_),
184209
sampler_properties_(other.sampler_properties_),
185210
allocator_(other.allocator_),
@@ -191,7 +216,8 @@ VulkanImage::VulkanImage(const VulkanImage& other) noexcept
191216
layout_(other.layout_) {}
192217

193218
VulkanImage::VulkanImage(VulkanImage&& other) noexcept
194-
: image_properties_(other.image_properties_),
219+
: device_(other.device_),
220+
image_properties_(other.image_properties_),
195221
view_properties_(other.view_properties_),
196222
sampler_properties_(other.sampler_properties_),
197223
allocator_(other.allocator_),
@@ -212,6 +238,7 @@ VulkanImage& VulkanImage::operator=(VulkanImage&& other) noexcept {
212238
VkImageView tmp_image_view = handles_.image_view;
213239
bool tmp_owns_memory = owns_memory_;
214240

241+
device_ = other.device_;
215242
image_properties_ = other.image_properties_;
216243
view_properties_ = other.view_properties_;
217244
sampler_properties_ = other.sampler_properties_;

backends/vulkan/runtime/vk_api/memory/Image.h

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ class VulkanImage final {
9393
explicit VulkanImage();
9494

9595
explicit VulkanImage(
96+
VkDevice,
9697
const VmaAllocator,
9798
const VmaAllocationCreateInfo&,
9899
const ImageProperties&,
@@ -102,6 +103,13 @@ class VulkanImage final {
102103
VkSampler,
103104
const bool allocate_memory = true);
104105

106+
explicit VulkanImage(
107+
VkDevice,
108+
const ImageProperties&,
109+
VkImage,
110+
VkImageView,
111+
VkSampler);
112+
105113
protected:
106114
/*
107115
* The Copy constructor allows for creation of a class instance that are
@@ -136,6 +144,7 @@ class VulkanImage final {
136144
friend struct ImageMemoryBarrier;
137145

138146
private:
147+
VkDevice device_;
139148
ImageProperties image_properties_;
140149
ViewProperties view_properties_;
141150
SamplerProperties sampler_properties_;
@@ -159,9 +168,7 @@ class VulkanImage final {
159168
void create_image_view();
160169

161170
inline VkDevice device() const {
162-
VmaAllocatorInfo allocator_info{};
163-
vmaGetAllocatorInfo(allocator_, &allocator_info);
164-
return allocator_info.device;
171+
return device_;
165172
}
166173

167174
inline VmaAllocator vma_allocator() const {

0 commit comments

Comments
 (0)