1b8e80941Smrg/*
2b8e80941Smrg * Copyright © 2017, Google Inc.
3b8e80941Smrg *
4b8e80941Smrg * Permission is hereby granted, free of charge, to any person obtaining a
5b8e80941Smrg * copy of this software and associated documentation files (the "Software"),
6b8e80941Smrg * to deal in the Software without restriction, including without limitation
7b8e80941Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8b8e80941Smrg * and/or sell copies of the Software, and to permit persons to whom the
9b8e80941Smrg * Software is furnished to do so, subject to the following conditions:
10b8e80941Smrg *
11b8e80941Smrg * The above copyright notice and this permission notice (including the next
12b8e80941Smrg * paragraph) shall be included in all copies or substantial portions of the
13b8e80941Smrg * Software.
14b8e80941Smrg *
15b8e80941Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16b8e80941Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17b8e80941Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18b8e80941Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19b8e80941Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20b8e80941Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21b8e80941Smrg * IN THE SOFTWARE.
22b8e80941Smrg */
23b8e80941Smrg
24b8e80941Smrg#include <hardware/gralloc.h>
25b8e80941Smrg#include <hardware/hardware.h>
26b8e80941Smrg#include <hardware/hwvulkan.h>
27b8e80941Smrg#include <vulkan/vk_android_native_buffer.h>
28b8e80941Smrg#include <vulkan/vk_icd.h>
29b8e80941Smrg#include <libsync.h>
30b8e80941Smrg
31b8e80941Smrg#include "radv_private.h"
32b8e80941Smrg
33b8e80941Smrgstatic int radv_hal_open(const struct hw_module_t* mod, const char* id, struct hw_device_t** dev);
34b8e80941Smrgstatic int radv_hal_close(struct hw_device_t *dev);
35b8e80941Smrg
36b8e80941Smrgstatic void UNUSED
37b8e80941Smrgstatic_asserts(void)
38b8e80941Smrg{
39b8e80941Smrg	STATIC_ASSERT(HWVULKAN_DISPATCH_MAGIC == ICD_LOADER_MAGIC);
40b8e80941Smrg}
41b8e80941Smrg
42b8e80941SmrgPUBLIC struct hwvulkan_module_t HAL_MODULE_INFO_SYM = {
43b8e80941Smrg	.common = {
44b8e80941Smrg		.tag = HARDWARE_MODULE_TAG,
45b8e80941Smrg		.module_api_version = HWVULKAN_MODULE_API_VERSION_0_1,
46b8e80941Smrg		.hal_api_version = HARDWARE_MAKE_API_VERSION(1, 0),
47b8e80941Smrg		.id = HWVULKAN_HARDWARE_MODULE_ID,
48b8e80941Smrg		.name = "AMD Vulkan HAL",
49b8e80941Smrg		.author = "Google",
50b8e80941Smrg		.methods = &(hw_module_methods_t) {
51b8e80941Smrg			.open = radv_hal_open,
52b8e80941Smrg		},
53b8e80941Smrg	},
54b8e80941Smrg};
55b8e80941Smrg
56b8e80941Smrg/* If any bits in test_mask are set, then unset them and return true. */
57b8e80941Smrgstatic inline bool
58b8e80941Smrgunmask32(uint32_t *inout_mask, uint32_t test_mask)
59b8e80941Smrg{
60b8e80941Smrg	uint32_t orig_mask = *inout_mask;
61b8e80941Smrg	*inout_mask &= ~test_mask;
62b8e80941Smrg	return *inout_mask != orig_mask;
63b8e80941Smrg}
64b8e80941Smrg
65b8e80941Smrgstatic int
66b8e80941Smrgradv_hal_open(const struct hw_module_t* mod, const char* id,
67b8e80941Smrg             struct hw_device_t** dev)
68b8e80941Smrg{
69b8e80941Smrg	assert(mod == &HAL_MODULE_INFO_SYM.common);
70b8e80941Smrg	assert(strcmp(id, HWVULKAN_DEVICE_0) == 0);
71b8e80941Smrg
72b8e80941Smrg	hwvulkan_device_t *hal_dev = malloc(sizeof(*hal_dev));
73b8e80941Smrg	if (!hal_dev)
74b8e80941Smrg		return -1;
75b8e80941Smrg
76b8e80941Smrg	*hal_dev = (hwvulkan_device_t) {
77b8e80941Smrg		.common = {
78b8e80941Smrg			.tag = HARDWARE_DEVICE_TAG,
79b8e80941Smrg			.version = HWVULKAN_DEVICE_API_VERSION_0_1,
80b8e80941Smrg			.module = &HAL_MODULE_INFO_SYM.common,
81b8e80941Smrg			.close = radv_hal_close,
82b8e80941Smrg		},
83b8e80941Smrg		.EnumerateInstanceExtensionProperties = radv_EnumerateInstanceExtensionProperties,
84b8e80941Smrg		.CreateInstance = radv_CreateInstance,
85b8e80941Smrg		.GetInstanceProcAddr = radv_GetInstanceProcAddr,
86b8e80941Smrg	};
87b8e80941Smrg
88b8e80941Smrg	*dev = &hal_dev->common;
89b8e80941Smrg	return 0;
90b8e80941Smrg}
91b8e80941Smrg
92b8e80941Smrgstatic int
93b8e80941Smrgradv_hal_close(struct hw_device_t *dev)
94b8e80941Smrg{
95b8e80941Smrg	/* hwvulkan.h claims that hw_device_t::close() is never called. */
96b8e80941Smrg	return -1;
97b8e80941Smrg}
98b8e80941Smrg
99b8e80941SmrgVkResult
100b8e80941Smrgradv_image_from_gralloc(VkDevice device_h,
101b8e80941Smrg                       const VkImageCreateInfo *base_info,
102b8e80941Smrg                       const VkNativeBufferANDROID *gralloc_info,
103b8e80941Smrg                       const VkAllocationCallbacks *alloc,
104b8e80941Smrg                       VkImage *out_image_h)
105b8e80941Smrg
106b8e80941Smrg{
107b8e80941Smrg	RADV_FROM_HANDLE(radv_device, device, device_h);
108b8e80941Smrg	VkImage image_h = VK_NULL_HANDLE;
109b8e80941Smrg	struct radv_image *image = NULL;
110b8e80941Smrg	struct radv_bo *bo = NULL;
111b8e80941Smrg	VkResult result;
112b8e80941Smrg
113b8e80941Smrg	if (gralloc_info->handle->numFds != 1) {
114b8e80941Smrg		return vk_errorf(device->instance, VK_ERROR_INVALID_EXTERNAL_HANDLE,
115b8e80941Smrg		                 "VkNativeBufferANDROID::handle::numFds is %d, "
116b8e80941Smrg		                 "expected 1", gralloc_info->handle->numFds);
117b8e80941Smrg	}
118b8e80941Smrg
119b8e80941Smrg	/* Do not close the gralloc handle's dma_buf. The lifetime of the dma_buf
120b8e80941Smrg	 * must exceed that of the gralloc handle, and we do not own the gralloc
121b8e80941Smrg	 * handle.
122b8e80941Smrg	 */
123b8e80941Smrg	int dma_buf = gralloc_info->handle->data[0];
124b8e80941Smrg
125b8e80941Smrg	VkDeviceMemory memory_h;
126b8e80941Smrg
127b8e80941Smrg	const VkImportMemoryFdInfoKHR import_info = {
128b8e80941Smrg		.sType = VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR,
129b8e80941Smrg		.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT,
130b8e80941Smrg		.fd = dup(dma_buf),
131b8e80941Smrg	};
132b8e80941Smrg
133b8e80941Smrg	/* Find the first VRAM memory type, or GART for PRIME images. */
134b8e80941Smrg	int memory_type_index = -1;
135b8e80941Smrg	for (int i = 0; i < device->physical_device->memory_properties.memoryTypeCount; ++i) {
136b8e80941Smrg		bool is_local = !!(device->physical_device->memory_properties.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
137b8e80941Smrg		if (is_local) {
138b8e80941Smrg			memory_type_index = i;
139b8e80941Smrg			break;
140b8e80941Smrg		}
141b8e80941Smrg	}
142b8e80941Smrg
143b8e80941Smrg	/* fallback */
144b8e80941Smrg	if (memory_type_index == -1)
145b8e80941Smrg		memory_type_index = 0;
146b8e80941Smrg
147b8e80941Smrg	result = radv_AllocateMemory(device_h,
148b8e80941Smrg				     &(VkMemoryAllocateInfo) {
149b8e80941Smrg					     .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
150b8e80941Smrg					     .pNext = &import_info,
151b8e80941Smrg					     /* Max buffer size, unused for imports */
152b8e80941Smrg					     .allocationSize = 0x7FFFFFFF,
153b8e80941Smrg					     .memoryTypeIndex = memory_type_index,
154b8e80941Smrg				     },
155b8e80941Smrg				     alloc,
156b8e80941Smrg				     &memory_h);
157b8e80941Smrg	if (result != VK_SUCCESS)
158b8e80941Smrg		return result;
159b8e80941Smrg
160b8e80941Smrg	struct radeon_bo_metadata md;
161b8e80941Smrg	device->ws->buffer_get_metadata(radv_device_memory_from_handle(memory_h)->bo, &md);
162b8e80941Smrg
163b8e80941Smrg	bool is_scanout;
164b8e80941Smrg	if (device->physical_device->rad_info.chip_class >= GFX9) {
165b8e80941Smrg		/* Copied from radeonsi, but is hacky so should be cleaned up. */
166b8e80941Smrg		is_scanout =  md.u.gfx9.swizzle_mode == 0 || md.u.gfx9.swizzle_mode % 4 == 2;
167b8e80941Smrg	} else {
168b8e80941Smrg		is_scanout = md.u.legacy.scanout;
169b8e80941Smrg	}
170b8e80941Smrg
171b8e80941Smrg	VkImageCreateInfo updated_base_info = *base_info;
172b8e80941Smrg
173b8e80941Smrg	VkExternalMemoryImageCreateInfo external_memory_info = {
174b8e80941Smrg		.sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO,
175b8e80941Smrg		.pNext = updated_base_info.pNext,
176b8e80941Smrg		.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,
177b8e80941Smrg	};
178b8e80941Smrg
179b8e80941Smrg	updated_base_info.pNext = &external_memory_info;
180b8e80941Smrg
181b8e80941Smrg	result = radv_image_create(device_h,
182b8e80941Smrg	                           &(struct radv_image_create_info) {
183b8e80941Smrg	                               .vk_info = &updated_base_info,
184b8e80941Smrg	                               .scanout = is_scanout,
185b8e80941Smrg	                               .no_metadata_planes = true},
186b8e80941Smrg	                           alloc,
187b8e80941Smrg	                           &image_h);
188b8e80941Smrg
189b8e80941Smrg	if (result != VK_SUCCESS)
190b8e80941Smrg		goto fail_create_image;
191b8e80941Smrg
192b8e80941Smrg	image = radv_image_from_handle(image_h);
193b8e80941Smrg
194b8e80941Smrg	radv_BindImageMemory(device_h, image_h, memory_h, 0);
195b8e80941Smrg
196b8e80941Smrg	image->owned_memory = memory_h;
197b8e80941Smrg	/* Don't clobber the out-parameter until success is certain. */
198b8e80941Smrg	*out_image_h = image_h;
199b8e80941Smrg
200b8e80941Smrg	return VK_SUCCESS;
201b8e80941Smrg
202b8e80941Smrgfail_create_image:
203b8e80941Smrg	radv_FreeMemory(device_h, memory_h, alloc);
204b8e80941Smrg	return result;
205b8e80941Smrg}
206b8e80941Smrg
207b8e80941SmrgVkResult radv_GetSwapchainGrallocUsageANDROID(
208b8e80941Smrg    VkDevice            device_h,
209b8e80941Smrg    VkFormat            format,
210b8e80941Smrg    VkImageUsageFlags   imageUsage,
211b8e80941Smrg    int*                grallocUsage)
212b8e80941Smrg{
213b8e80941Smrg	RADV_FROM_HANDLE(radv_device, device, device_h);
214b8e80941Smrg	struct radv_physical_device *phys_dev = device->physical_device;
215b8e80941Smrg	VkPhysicalDevice phys_dev_h = radv_physical_device_to_handle(phys_dev);
216b8e80941Smrg	VkResult result;
217b8e80941Smrg
218b8e80941Smrg	*grallocUsage = 0;
219b8e80941Smrg
220b8e80941Smrg	/* WARNING: Android Nougat's libvulkan.so hardcodes the VkImageUsageFlags
221b8e80941Smrg	 * returned to applications via VkSurfaceCapabilitiesKHR::supportedUsageFlags.
222b8e80941Smrg	 * The relevant code in libvulkan/swapchain.cpp contains this fun comment:
223b8e80941Smrg	 *
224b8e80941Smrg	 *     TODO(jessehall): I think these are right, but haven't thought hard
225b8e80941Smrg	 *     about it. Do we need to query the driver for support of any of
226b8e80941Smrg	 *     these?
227b8e80941Smrg	 *
228b8e80941Smrg	 * Any disagreement between this function and the hardcoded
229b8e80941Smrg	 * VkSurfaceCapabilitiesKHR:supportedUsageFlags causes tests
230b8e80941Smrg	 * dEQP-VK.wsi.android.swapchain.*.image_usage to fail.
231b8e80941Smrg	 */
232b8e80941Smrg
233b8e80941Smrg	const VkPhysicalDeviceImageFormatInfo2 image_format_info = {
234b8e80941Smrg		.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
235b8e80941Smrg		.format = format,
236b8e80941Smrg		.type = VK_IMAGE_TYPE_2D,
237b8e80941Smrg		.tiling = VK_IMAGE_TILING_OPTIMAL,
238b8e80941Smrg		.usage = imageUsage,
239b8e80941Smrg	};
240b8e80941Smrg
241b8e80941Smrg	VkImageFormatProperties2 image_format_props = {
242b8e80941Smrg		.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2,
243b8e80941Smrg	};
244b8e80941Smrg
245b8e80941Smrg	/* Check that requested format and usage are supported. */
246b8e80941Smrg	result = radv_GetPhysicalDeviceImageFormatProperties2(phys_dev_h,
247b8e80941Smrg	                                                      &image_format_info, &image_format_props);
248b8e80941Smrg	if (result != VK_SUCCESS) {
249b8e80941Smrg		return vk_errorf(device->instance, result,
250b8e80941Smrg		                 "radv_GetPhysicalDeviceImageFormatProperties2 failed "
251b8e80941Smrg		                 "inside %s", __func__);
252b8e80941Smrg	}
253b8e80941Smrg
254b8e80941Smrg	if (unmask32(&imageUsage, VK_IMAGE_USAGE_TRANSFER_DST_BIT |
255b8e80941Smrg	                          VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT))
256b8e80941Smrg		*grallocUsage |= GRALLOC_USAGE_HW_RENDER;
257b8e80941Smrg
258b8e80941Smrg	if (unmask32(&imageUsage, VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
259b8e80941Smrg	                          VK_IMAGE_USAGE_SAMPLED_BIT |
260b8e80941Smrg	                          VK_IMAGE_USAGE_STORAGE_BIT |
261b8e80941Smrg	                          VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT))
262b8e80941Smrg		*grallocUsage |= GRALLOC_USAGE_HW_TEXTURE;
263b8e80941Smrg
264b8e80941Smrg	/* All VkImageUsageFlags not explicitly checked here are unsupported for
265b8e80941Smrg	 * gralloc swapchains.
266b8e80941Smrg	 */
267b8e80941Smrg	if (imageUsage != 0) {
268b8e80941Smrg	return vk_errorf(device->instance, VK_ERROR_FORMAT_NOT_SUPPORTED,
269b8e80941Smrg	                "unsupported VkImageUsageFlags(0x%x) for gralloc "
270b8e80941Smrg	                "swapchain", imageUsage);
271b8e80941Smrg	}
272b8e80941Smrg
273b8e80941Smrg	/*
274b8e80941Smrg	* FINISHME: Advertise all display-supported formats. Mostly
275b8e80941Smrg	* DRM_FORMAT_ARGB2101010 and DRM_FORMAT_ABGR2101010, but need to check
276b8e80941Smrg	* what we need for 30-bit colors.
277b8e80941Smrg	*/
278b8e80941Smrg	if (format == VK_FORMAT_B8G8R8A8_UNORM ||
279b8e80941Smrg	    format == VK_FORMAT_B5G6R5_UNORM_PACK16) {
280b8e80941Smrg		*grallocUsage |= GRALLOC_USAGE_HW_FB |
281b8e80941Smrg		                 GRALLOC_USAGE_HW_COMPOSER |
282b8e80941Smrg		                 GRALLOC_USAGE_EXTERNAL_DISP;
283b8e80941Smrg	}
284b8e80941Smrg
285b8e80941Smrg	if (*grallocUsage == 0)
286b8e80941Smrg		return VK_ERROR_FORMAT_NOT_SUPPORTED;
287b8e80941Smrg
288b8e80941Smrg	return VK_SUCCESS;
289b8e80941Smrg}
290b8e80941Smrg
291b8e80941SmrgVkResult
292b8e80941Smrgradv_AcquireImageANDROID(
293b8e80941Smrg      VkDevice            device,
294b8e80941Smrg      VkImage             image_h,
295b8e80941Smrg      int                 nativeFenceFd,
296b8e80941Smrg      VkSemaphore         semaphore,
297b8e80941Smrg      VkFence             fence)
298b8e80941Smrg{
299b8e80941Smrg	VkResult semaphore_result = VK_SUCCESS, fence_result = VK_SUCCESS;
300b8e80941Smrg
301b8e80941Smrg	if (semaphore != VK_NULL_HANDLE) {
302b8e80941Smrg		int semaphore_fd = nativeFenceFd >= 0 ? dup(nativeFenceFd) : nativeFenceFd;
303b8e80941Smrg		semaphore_result = radv_ImportSemaphoreFdKHR(device,
304b8e80941Smrg		                                             &(VkImportSemaphoreFdInfoKHR) {
305b8e80941Smrg		                                                 .sType = VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR,
306b8e80941Smrg		                                                 .flags = VK_SEMAPHORE_IMPORT_TEMPORARY_BIT,
307b8e80941Smrg		                                                 .fd = semaphore_fd,
308b8e80941Smrg		                                                 .semaphore = semaphore,
309b8e80941Smrg		                                            });
310b8e80941Smrg	}
311b8e80941Smrg
312b8e80941Smrg	if (fence != VK_NULL_HANDLE) {
313b8e80941Smrg		int fence_fd = nativeFenceFd >= 0 ? dup(nativeFenceFd) : nativeFenceFd;
314b8e80941Smrg		fence_result = radv_ImportFenceFdKHR(device,
315b8e80941Smrg		                                     &(VkImportFenceFdInfoKHR) {
316b8e80941Smrg		                                         .sType = VK_STRUCTURE_TYPE_IMPORT_FENCE_FD_INFO_KHR,
317b8e80941Smrg		                                         .flags = VK_FENCE_IMPORT_TEMPORARY_BIT,
318b8e80941Smrg		                                         .fd = fence_fd,
319b8e80941Smrg		                                         .fence = fence,
320b8e80941Smrg		                                     });
321b8e80941Smrg	}
322b8e80941Smrg
323b8e80941Smrg	close(nativeFenceFd);
324b8e80941Smrg
325b8e80941Smrg	if (semaphore_result != VK_SUCCESS)
326b8e80941Smrg		return semaphore_result;
327b8e80941Smrg	return fence_result;
328b8e80941Smrg}
329b8e80941Smrg
330b8e80941SmrgVkResult
331b8e80941Smrgradv_QueueSignalReleaseImageANDROID(
332b8e80941Smrg      VkQueue             _queue,
333b8e80941Smrg      uint32_t            waitSemaphoreCount,
334b8e80941Smrg      const VkSemaphore*  pWaitSemaphores,
335b8e80941Smrg      VkImage             image,
336b8e80941Smrg      int*                pNativeFenceFd)
337b8e80941Smrg{
338b8e80941Smrg	RADV_FROM_HANDLE(radv_queue, queue, _queue);
339b8e80941Smrg	VkResult result = VK_SUCCESS;
340b8e80941Smrg
341b8e80941Smrg	if (waitSemaphoreCount == 0) {
342b8e80941Smrg		if (pNativeFenceFd)
343b8e80941Smrg			*pNativeFenceFd = -1;
344b8e80941Smrg		return VK_SUCCESS;
345b8e80941Smrg	}
346b8e80941Smrg
347b8e80941Smrg	int fd = -1;
348b8e80941Smrg
349b8e80941Smrg	for (uint32_t i = 0; i < waitSemaphoreCount; ++i) {
350b8e80941Smrg		int tmp_fd;
351b8e80941Smrg		result = radv_GetSemaphoreFdKHR(radv_device_to_handle(queue->device),
352b8e80941Smrg		                                &(VkSemaphoreGetFdInfoKHR) {
353b8e80941Smrg		                                    .sType = VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR,
354b8e80941Smrg		                                    .handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT,
355b8e80941Smrg		                                    .semaphore = pWaitSemaphores[i],
356b8e80941Smrg		                            }, &tmp_fd);
357b8e80941Smrg		if (result != VK_SUCCESS) {
358b8e80941Smrg			if (fd >= 0)
359b8e80941Smrg				close (fd);
360b8e80941Smrg			return result;
361b8e80941Smrg		}
362b8e80941Smrg
363b8e80941Smrg		if (fd < 0)
364b8e80941Smrg			fd = tmp_fd;
365b8e80941Smrg		else if (tmp_fd >= 0) {
366b8e80941Smrg			sync_accumulate("radv", &fd, tmp_fd);
367b8e80941Smrg			close(tmp_fd);
368b8e80941Smrg		}
369b8e80941Smrg	}
370b8e80941Smrg
371b8e80941Smrg	if (pNativeFenceFd) {
372b8e80941Smrg		*pNativeFenceFd = fd;
373b8e80941Smrg	} else if (fd >= 0) {
374b8e80941Smrg		close(fd);
375b8e80941Smrg		/* We still need to do the exports, to reset the semaphores, but
376b8e80941Smrg		 * otherwise we don't wait on them. */
377b8e80941Smrg	}
378b8e80941Smrg	return VK_SUCCESS;
379b8e80941Smrg}
380