• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /// Copyright (C) 2019 The Android Open Source Project
2 // Copyright (C) 2019 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 #include "AndroidHardwareBuffer.h"
16 
17 #include "gralloc_cb.h"
18 #include "vk_format_info.h"
19 #include "vk_util.h"
20 
21 namespace goldfish_vk {
22 
23 // From Intel ANV implementation.
24 /* Construct ahw usage mask from image usage bits, see
25  * 'AHardwareBuffer Usage Equivalence' in Vulkan spec.
26  */
27 uint64_t
getAndroidHardwareBufferUsageFromVkUsage(const VkImageCreateFlags vk_create,const VkImageUsageFlags vk_usage)28 getAndroidHardwareBufferUsageFromVkUsage(const VkImageCreateFlags vk_create,
29                                  const VkImageUsageFlags vk_usage)
30 {
31    uint64_t ahw_usage = 0;
32 
33    if (vk_usage & VK_IMAGE_USAGE_SAMPLED_BIT)
34       ahw_usage |= AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
35 
36    if (vk_usage & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)
37       ahw_usage |= AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
38 
39    if (vk_usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)
40       ahw_usage |= AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT;
41 
42    if (vk_create & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT)
43       ahw_usage |= AHARDWAREBUFFER_USAGE_GPU_CUBE_MAP;
44 
45    if (vk_create & VK_IMAGE_CREATE_PROTECTED_BIT)
46       ahw_usage |= AHARDWAREBUFFER_USAGE_PROTECTED_CONTENT;
47 
48    /* No usage bits set - set at least one GPU usage. */
49    if (ahw_usage == 0)
50       ahw_usage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
51 
52    return ahw_usage;
53 }
54 
getAndroidHardwareBufferPropertiesANDROID(const HostVisibleMemoryVirtualizationInfo * hostMemVirtInfo,VkDevice,const AHardwareBuffer * buffer,VkAndroidHardwareBufferPropertiesANDROID * pProperties)55 VkResult getAndroidHardwareBufferPropertiesANDROID(
56     const HostVisibleMemoryVirtualizationInfo* hostMemVirtInfo,
57     VkDevice,
58     const AHardwareBuffer* buffer,
59     VkAndroidHardwareBufferPropertiesANDROID* pProperties) {
60 
61     VkAndroidHardwareBufferFormatPropertiesANDROID* ahbFormatProps =
62         vk_find_struct<VkAndroidHardwareBufferFormatPropertiesANDROID>(pProperties);
63 
64     if (ahbFormatProps) {
65         AHardwareBuffer_Desc desc;
66         AHardwareBuffer_describe(buffer, &desc);
67 
68        const uint64_t gpu_usage =
69           AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE |
70           AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT |
71           AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER;
72 
73         if (!(desc.usage & (gpu_usage))) {
74             return VK_ERROR_INVALID_EXTERNAL_HANDLE;
75         }
76 
77         ahbFormatProps->format = vk_format_from_android(desc.format);
78         ahbFormatProps->externalFormat = desc.format;
79 
80         // The formatFeatures member must include
81         // VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT and at least one of
82         // VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT or
83         // VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT, and should include
84         // VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT and
85         // VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT.
86 
87         ahbFormatProps->formatFeatures =
88             VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT |
89             VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT;
90 
91         // "Implementations may not always be able to determine the color model,
92         // numerical range, or chroma offsets of the image contents, so the values in
93         // VkAndroidHardwareBufferFormatPropertiesANDROID are only suggestions.
94         // Applications should treat these values as sensible defaults to use in the
95         // absence of more reliable information obtained through some other means."
96 
97         ahbFormatProps->samplerYcbcrConversionComponents.r = VK_COMPONENT_SWIZZLE_IDENTITY;
98         ahbFormatProps->samplerYcbcrConversionComponents.g = VK_COMPONENT_SWIZZLE_IDENTITY;
99         ahbFormatProps->samplerYcbcrConversionComponents.b = VK_COMPONENT_SWIZZLE_IDENTITY;
100         ahbFormatProps->samplerYcbcrConversionComponents.a = VK_COMPONENT_SWIZZLE_IDENTITY;
101 
102         ahbFormatProps->suggestedYcbcrModel =
103             android_format_is_yuv(desc.format) ?
104                 VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_601 :
105                 VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY;
106         ahbFormatProps->suggestedYcbcrRange = VK_SAMPLER_YCBCR_RANGE_ITU_FULL;
107 
108         ahbFormatProps->suggestedXChromaOffset = VK_CHROMA_LOCATION_MIDPOINT;
109         ahbFormatProps->suggestedYChromaOffset = VK_CHROMA_LOCATION_MIDPOINT;
110     }
111 
112     const native_handle_t *handle =
113        AHardwareBuffer_getNativeHandle(buffer);
114     const cb_handle_t* cb_handle =
115         reinterpret_cast<const cb_handle_t*>(handle);
116     uint32_t colorBufferHandle = cb_handle->hostHandle;
117 
118     if (!colorBufferHandle) {
119         return VK_ERROR_INVALID_EXTERNAL_HANDLE;
120     }
121 
122     // Disallow host visible and noflags heaps for now
123     // (hard to make actual dedicated allocs)
124     uint32_t memoryTypeBits = 0;
125     for (uint32_t i = 0; i < VK_MAX_MEMORY_TYPES; ++i) {
126         if (isNoFlagsMemoryTypeIndexForGuest(hostMemVirtInfo, i)) continue;
127         if (isHostVisibleMemoryTypeIndexForGuest(hostMemVirtInfo, i)) continue;
128         memoryTypeBits |= (1 << i);
129     }
130 
131     pProperties->memoryTypeBits = memoryTypeBits;
132     pProperties->allocationSize =
133         cb_handle->ashmemBase ? cb_handle->ashmemSize : 0;
134 
135     return VK_SUCCESS;
136 }
137 
138 // Based on Intel ANV implementation.
getMemoryAndroidHardwareBufferANDROID(struct AHardwareBuffer ** pBuffer)139 VkResult getMemoryAndroidHardwareBufferANDROID(struct AHardwareBuffer **pBuffer) {
140 
141    /* Some quotes from Vulkan spec:
142     *
143     * "If the device memory was created by importing an Android hardware
144     * buffer, vkGetMemoryAndroidHardwareBufferANDROID must return that same
145     * Android hardware buffer object."
146     *
147     * "VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID must
148     * have been included in VkExportMemoryAllocateInfo::handleTypes when
149     * memory was created."
150     */
151 
152     if (!pBuffer) return VK_ERROR_OUT_OF_HOST_MEMORY;
153     if (!(*pBuffer)) return VK_ERROR_OUT_OF_HOST_MEMORY;
154 
155     AHardwareBuffer_acquire(*pBuffer);
156     return VK_SUCCESS;
157 }
158 
importAndroidHardwareBuffer(const VkImportAndroidHardwareBufferInfoANDROID * info,struct AHardwareBuffer ** importOut)159 VkResult importAndroidHardwareBuffer(
160     const VkImportAndroidHardwareBufferInfoANDROID* info,
161     struct AHardwareBuffer **importOut) {
162 
163     if (!info || !info->buffer) {
164         return VK_ERROR_INVALID_EXTERNAL_HANDLE;
165     }
166 
167     const native_handle_t *handle =
168        AHardwareBuffer_getNativeHandle(info->buffer);
169     const cb_handle_t* cb_handle =
170         reinterpret_cast<const cb_handle_t*>(handle);
171     uint32_t colorBufferHandle = cb_handle->hostHandle;
172 
173     if (!colorBufferHandle) {
174         return VK_ERROR_INVALID_EXTERNAL_HANDLE;
175     }
176 
177     auto ahb = info->buffer;
178 
179     AHardwareBuffer_acquire(ahb);
180 
181     if (importOut) *importOut = ahb;
182 
183     return VK_SUCCESS;
184 }
185 
createAndroidHardwareBuffer(bool hasDedicatedImage,bool hasDedicatedBuffer,const VkExtent3D & imageExtent,uint32_t imageLayers,VkFormat imageFormat,VkImageUsageFlags imageUsage,VkImageCreateFlags imageCreateFlags,VkDeviceSize bufferSize,VkDeviceSize allocationInfoAllocSize,struct AHardwareBuffer ** out)186 VkResult createAndroidHardwareBuffer(
187     bool hasDedicatedImage,
188     bool hasDedicatedBuffer,
189     const VkExtent3D& imageExtent,
190     uint32_t imageLayers,
191     VkFormat imageFormat,
192     VkImageUsageFlags imageUsage,
193     VkImageCreateFlags imageCreateFlags,
194     VkDeviceSize bufferSize,
195     VkDeviceSize allocationInfoAllocSize,
196     struct AHardwareBuffer **out) {
197 
198     uint32_t w = 0;
199     uint32_t h = 1;
200     uint32_t layers = 1;
201     uint32_t format = 0;
202     uint64_t usage = 0;
203 
204     /* If caller passed dedicated information. */
205     if (hasDedicatedImage) {
206        w = imageExtent.width;
207        h = imageExtent.height;
208        layers = imageLayers;
209        format = android_format_from_vk(imageFormat);
210        usage = getAndroidHardwareBufferUsageFromVkUsage(imageCreateFlags, imageUsage);
211     } else if (hasDedicatedBuffer) {
212        w = bufferSize;
213        format = AHARDWAREBUFFER_FORMAT_BLOB;
214        usage = AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN |
215                AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN;
216     } else {
217        w = allocationInfoAllocSize;
218        format = AHARDWAREBUFFER_FORMAT_BLOB;
219        usage = AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN |
220                AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN;
221     }
222 
223     struct AHardwareBuffer *ahw = NULL;
224     struct AHardwareBuffer_Desc desc = {
225         .width = w,
226         .height = h,
227         .layers = layers,
228         .format = format,
229         .usage = usage,
230     };
231 
232     if (AHardwareBuffer_allocate(&desc, &ahw) != 0) {
233         return VK_ERROR_OUT_OF_HOST_MEMORY;
234     }
235 
236     *out = ahw;
237 
238     return VK_SUCCESS;
239 }
240 
241 } // namespace goldfish_vk
242