1bf215546Sopenharmony_ci/*
2bf215546Sopenharmony_ci * Copyright © 2021 Collabora Ltd.
3bf215546Sopenharmony_ci *
4bf215546Sopenharmony_ci * Derived from tu_formats.c which is:
5bf215546Sopenharmony_ci * Copyright © 2016 Red Hat.
6bf215546Sopenharmony_ci * Copyright © 2016 Bas Nieuwenhuizen
7bf215546Sopenharmony_ci *
8bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
9bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"),
10bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation
11bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the
13bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions:
14bf215546Sopenharmony_ci *
15bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next
16bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the
17bf215546Sopenharmony_ci * Software.
18bf215546Sopenharmony_ci *
19bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
22bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24bf215546Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25bf215546Sopenharmony_ci * DEALINGS IN THE SOFTWARE.
26bf215546Sopenharmony_ci */
27bf215546Sopenharmony_ci
28bf215546Sopenharmony_ci#include "panvk_private.h"
29bf215546Sopenharmony_ci
30bf215546Sopenharmony_ci#include "util/format_r11g11b10f.h"
31bf215546Sopenharmony_ci#include "util/format_srgb.h"
32bf215546Sopenharmony_ci#include "util/half_float.h"
33bf215546Sopenharmony_ci#include "vulkan/util/vk_format.h"
34bf215546Sopenharmony_ci#include "vk_format.h"
35bf215546Sopenharmony_ci#include "vk_util.h"
36bf215546Sopenharmony_ci#include "panfrost/lib/pan_texture.h"
37bf215546Sopenharmony_ci
38bf215546Sopenharmony_cistatic void
39bf215546Sopenharmony_ciget_format_properties(struct panvk_physical_device *physical_device,
40bf215546Sopenharmony_ci                      VkFormat format,
41bf215546Sopenharmony_ci                      VkFormatProperties *out_properties)
42bf215546Sopenharmony_ci{
43bf215546Sopenharmony_ci   struct panfrost_device *pdev = &physical_device->pdev;
44bf215546Sopenharmony_ci   VkFormatFeatureFlags tex = 0, buffer = 0;
45bf215546Sopenharmony_ci   enum pipe_format pfmt = vk_format_to_pipe_format(format);
46bf215546Sopenharmony_ci   const struct panfrost_format fmt = pdev->formats[pfmt];
47bf215546Sopenharmony_ci
48bf215546Sopenharmony_ci   if (!pfmt || !fmt.hw)
49bf215546Sopenharmony_ci      goto end;
50bf215546Sopenharmony_ci
51bf215546Sopenharmony_ci   /* 3byte formats are not supported by the buffer <-> image copy helpers. */
52bf215546Sopenharmony_ci   if (util_format_get_blocksize(pfmt) == 3)
53bf215546Sopenharmony_ci      goto end;
54bf215546Sopenharmony_ci
55bf215546Sopenharmony_ci   /* We don't support compressed formats yet: this is causing trouble when
56bf215546Sopenharmony_ci    * doing a vkCmdCopyImage() between a compressed and a non-compressed format
57bf215546Sopenharmony_ci    * on a tiled/AFBC resource.
58bf215546Sopenharmony_ci    */
59bf215546Sopenharmony_ci   if (util_format_is_compressed(pfmt))
60bf215546Sopenharmony_ci      goto end;
61bf215546Sopenharmony_ci
62bf215546Sopenharmony_ci   buffer |= VK_FORMAT_FEATURE_TRANSFER_SRC_BIT |
63bf215546Sopenharmony_ci             VK_FORMAT_FEATURE_TRANSFER_DST_BIT;
64bf215546Sopenharmony_ci
65bf215546Sopenharmony_ci   if (fmt.bind & PIPE_BIND_VERTEX_BUFFER)
66bf215546Sopenharmony_ci      buffer |= VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT;
67bf215546Sopenharmony_ci
68bf215546Sopenharmony_ci   if (fmt.bind & PIPE_BIND_SAMPLER_VIEW) {
69bf215546Sopenharmony_ci      tex |= VK_FORMAT_FEATURE_TRANSFER_SRC_BIT |
70bf215546Sopenharmony_ci             VK_FORMAT_FEATURE_TRANSFER_DST_BIT |
71bf215546Sopenharmony_ci             VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT |
72bf215546Sopenharmony_ci             VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT |
73bf215546Sopenharmony_ci             VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT;
74bf215546Sopenharmony_ci
75bf215546Sopenharmony_ci      /* Integer formats only support nearest filtering */
76bf215546Sopenharmony_ci      if (!util_format_is_scaled(pfmt) &&
77bf215546Sopenharmony_ci          !util_format_is_pure_integer(pfmt))
78bf215546Sopenharmony_ci         tex |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT;
79bf215546Sopenharmony_ci
80bf215546Sopenharmony_ci      buffer |= VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT;
81bf215546Sopenharmony_ci
82bf215546Sopenharmony_ci      tex |= VK_FORMAT_FEATURE_BLIT_SRC_BIT;
83bf215546Sopenharmony_ci   }
84bf215546Sopenharmony_ci
85bf215546Sopenharmony_ci   if (fmt.bind & PIPE_BIND_RENDER_TARGET) {
86bf215546Sopenharmony_ci      tex |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT |
87bf215546Sopenharmony_ci             VK_FORMAT_FEATURE_BLIT_DST_BIT;
88bf215546Sopenharmony_ci
89bf215546Sopenharmony_ci      tex |= VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT;
90bf215546Sopenharmony_ci      buffer |= VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT;
91bf215546Sopenharmony_ci
92bf215546Sopenharmony_ci      /* Can always blend via blend shaders */
93bf215546Sopenharmony_ci      tex |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT;
94bf215546Sopenharmony_ci   }
95bf215546Sopenharmony_ci
96bf215546Sopenharmony_ci   if (fmt.bind & PIPE_BIND_DEPTH_STENCIL)
97bf215546Sopenharmony_ci         tex |= VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT;
98bf215546Sopenharmony_ci
99bf215546Sopenharmony_ciend:
100bf215546Sopenharmony_ci   out_properties->linearTilingFeatures = tex;
101bf215546Sopenharmony_ci   out_properties->optimalTilingFeatures = tex;
102bf215546Sopenharmony_ci   out_properties->bufferFeatures = buffer;
103bf215546Sopenharmony_ci}
104bf215546Sopenharmony_ci
105bf215546Sopenharmony_civoid
106bf215546Sopenharmony_cipanvk_GetPhysicalDeviceFormatProperties(VkPhysicalDevice physicalDevice,
107bf215546Sopenharmony_ci                                      VkFormat format,
108bf215546Sopenharmony_ci                                      VkFormatProperties *pFormatProperties)
109bf215546Sopenharmony_ci{
110bf215546Sopenharmony_ci   VK_FROM_HANDLE(panvk_physical_device, physical_device, physicalDevice);
111bf215546Sopenharmony_ci
112bf215546Sopenharmony_ci   get_format_properties(physical_device, format, pFormatProperties);
113bf215546Sopenharmony_ci}
114bf215546Sopenharmony_ci
115bf215546Sopenharmony_civoid
116bf215546Sopenharmony_cipanvk_GetPhysicalDeviceFormatProperties2(VkPhysicalDevice physicalDevice,
117bf215546Sopenharmony_ci                                         VkFormat format,
118bf215546Sopenharmony_ci                                         VkFormatProperties2 *pFormatProperties)
119bf215546Sopenharmony_ci{
120bf215546Sopenharmony_ci   VK_FROM_HANDLE(panvk_physical_device, physical_device, physicalDevice);
121bf215546Sopenharmony_ci
122bf215546Sopenharmony_ci   get_format_properties(physical_device, format,
123bf215546Sopenharmony_ci                         &pFormatProperties->formatProperties);
124bf215546Sopenharmony_ci
125bf215546Sopenharmony_ci   VkDrmFormatModifierPropertiesListEXT *list =
126bf215546Sopenharmony_ci      vk_find_struct(pFormatProperties->pNext, DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT);
127bf215546Sopenharmony_ci   if (list) {
128bf215546Sopenharmony_ci      VK_OUTARRAY_MAKE_TYPED(VkDrmFormatModifierPropertiesEXT, out,
129bf215546Sopenharmony_ci                             list->pDrmFormatModifierProperties,
130bf215546Sopenharmony_ci                             &list->drmFormatModifierCount);
131bf215546Sopenharmony_ci
132bf215546Sopenharmony_ci      vk_outarray_append_typed(VkDrmFormatModifierProperties2EXT, &out, mod_props) {
133bf215546Sopenharmony_ci         mod_props->drmFormatModifier = DRM_FORMAT_MOD_LINEAR;
134bf215546Sopenharmony_ci         mod_props->drmFormatModifierPlaneCount = 1;
135bf215546Sopenharmony_ci      }
136bf215546Sopenharmony_ci   }
137bf215546Sopenharmony_ci}
138bf215546Sopenharmony_ci
139bf215546Sopenharmony_cistatic VkResult
140bf215546Sopenharmony_ciget_image_format_properties(struct panvk_physical_device *physical_device,
141bf215546Sopenharmony_ci                            const VkPhysicalDeviceImageFormatInfo2 *info,
142bf215546Sopenharmony_ci                            VkImageFormatProperties *pImageFormatProperties,
143bf215546Sopenharmony_ci                            VkFormatFeatureFlags *p_feature_flags)
144bf215546Sopenharmony_ci{
145bf215546Sopenharmony_ci   VkFormatProperties format_props;
146bf215546Sopenharmony_ci   VkFormatFeatureFlags format_feature_flags;
147bf215546Sopenharmony_ci   VkExtent3D maxExtent;
148bf215546Sopenharmony_ci   uint32_t maxMipLevels;
149bf215546Sopenharmony_ci   uint32_t maxArraySize;
150bf215546Sopenharmony_ci   VkSampleCountFlags sampleCounts = VK_SAMPLE_COUNT_1_BIT;
151bf215546Sopenharmony_ci   enum pipe_format format = vk_format_to_pipe_format(info->format);
152bf215546Sopenharmony_ci
153bf215546Sopenharmony_ci   get_format_properties(physical_device, info->format, &format_props);
154bf215546Sopenharmony_ci
155bf215546Sopenharmony_ci   switch (info->tiling) {
156bf215546Sopenharmony_ci   case VK_IMAGE_TILING_LINEAR:
157bf215546Sopenharmony_ci      format_feature_flags = format_props.linearTilingFeatures;
158bf215546Sopenharmony_ci      break;
159bf215546Sopenharmony_ci
160bf215546Sopenharmony_ci   case VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT:
161bf215546Sopenharmony_ci      /* The only difference between optimal and linear is currently whether
162bf215546Sopenharmony_ci       * depth/stencil attachments are allowed on depth/stencil formats.
163bf215546Sopenharmony_ci       * There's no reason to allow importing depth/stencil textures, so just
164bf215546Sopenharmony_ci       * disallow it and then this annoying edge case goes away.
165bf215546Sopenharmony_ci       *
166bf215546Sopenharmony_ci       * TODO: If anyone cares, we could enable this by looking at the
167bf215546Sopenharmony_ci       * modifier and checking if it's LINEAR or not.
168bf215546Sopenharmony_ci       */
169bf215546Sopenharmony_ci      if (util_format_is_depth_or_stencil(format))
170bf215546Sopenharmony_ci         goto unsupported;
171bf215546Sopenharmony_ci
172bf215546Sopenharmony_ci      assert(format_props.optimalTilingFeatures == format_props.linearTilingFeatures);
173bf215546Sopenharmony_ci      FALLTHROUGH;
174bf215546Sopenharmony_ci   case VK_IMAGE_TILING_OPTIMAL:
175bf215546Sopenharmony_ci      format_feature_flags = format_props.optimalTilingFeatures;
176bf215546Sopenharmony_ci      break;
177bf215546Sopenharmony_ci   default:
178bf215546Sopenharmony_ci      unreachable("bad VkPhysicalDeviceImageFormatInfo2");
179bf215546Sopenharmony_ci   }
180bf215546Sopenharmony_ci
181bf215546Sopenharmony_ci   if (format_feature_flags == 0)
182bf215546Sopenharmony_ci      goto unsupported;
183bf215546Sopenharmony_ci
184bf215546Sopenharmony_ci   if (info->type != VK_IMAGE_TYPE_2D &&
185bf215546Sopenharmony_ci       util_format_is_depth_or_stencil(format))
186bf215546Sopenharmony_ci      goto unsupported;
187bf215546Sopenharmony_ci
188bf215546Sopenharmony_ci   switch (info->type) {
189bf215546Sopenharmony_ci   default:
190bf215546Sopenharmony_ci      unreachable("bad vkimage type");
191bf215546Sopenharmony_ci   case VK_IMAGE_TYPE_1D:
192bf215546Sopenharmony_ci      maxExtent.width = 16384;
193bf215546Sopenharmony_ci      maxExtent.height = 1;
194bf215546Sopenharmony_ci      maxExtent.depth = 1;
195bf215546Sopenharmony_ci      maxMipLevels = 15; /* log2(maxWidth) + 1 */
196bf215546Sopenharmony_ci      maxArraySize = 2048;
197bf215546Sopenharmony_ci      break;
198bf215546Sopenharmony_ci   case VK_IMAGE_TYPE_2D:
199bf215546Sopenharmony_ci      maxExtent.width = 16384;
200bf215546Sopenharmony_ci      maxExtent.height = 16384;
201bf215546Sopenharmony_ci      maxExtent.depth = 1;
202bf215546Sopenharmony_ci      maxMipLevels = 15; /* log2(maxWidth) + 1 */
203bf215546Sopenharmony_ci      maxArraySize = 2048;
204bf215546Sopenharmony_ci      break;
205bf215546Sopenharmony_ci   case VK_IMAGE_TYPE_3D:
206bf215546Sopenharmony_ci      maxExtent.width = 2048;
207bf215546Sopenharmony_ci      maxExtent.height = 2048;
208bf215546Sopenharmony_ci      maxExtent.depth = 2048;
209bf215546Sopenharmony_ci      maxMipLevels = 12; /* log2(maxWidth) + 1 */
210bf215546Sopenharmony_ci      maxArraySize = 1;
211bf215546Sopenharmony_ci      break;
212bf215546Sopenharmony_ci   }
213bf215546Sopenharmony_ci
214bf215546Sopenharmony_ci   if (info->tiling == VK_IMAGE_TILING_OPTIMAL &&
215bf215546Sopenharmony_ci       info->type == VK_IMAGE_TYPE_2D &&
216bf215546Sopenharmony_ci       (format_feature_flags &
217bf215546Sopenharmony_ci        (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT |
218bf215546Sopenharmony_ci         VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)) &&
219bf215546Sopenharmony_ci       !(info->flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) &&
220bf215546Sopenharmony_ci       !(info->usage & VK_IMAGE_USAGE_STORAGE_BIT)) {
221bf215546Sopenharmony_ci      sampleCounts |= VK_SAMPLE_COUNT_4_BIT;
222bf215546Sopenharmony_ci   }
223bf215546Sopenharmony_ci
224bf215546Sopenharmony_ci   if (info->usage & VK_IMAGE_USAGE_SAMPLED_BIT) {
225bf215546Sopenharmony_ci      if (!(format_feature_flags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)) {
226bf215546Sopenharmony_ci         goto unsupported;
227bf215546Sopenharmony_ci      }
228bf215546Sopenharmony_ci   }
229bf215546Sopenharmony_ci
230bf215546Sopenharmony_ci   if (info->usage & VK_IMAGE_USAGE_STORAGE_BIT) {
231bf215546Sopenharmony_ci      if (!(format_feature_flags & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT)) {
232bf215546Sopenharmony_ci         goto unsupported;
233bf215546Sopenharmony_ci      }
234bf215546Sopenharmony_ci   }
235bf215546Sopenharmony_ci
236bf215546Sopenharmony_ci   if (info->usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) {
237bf215546Sopenharmony_ci      if (!(format_feature_flags & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT)) {
238bf215546Sopenharmony_ci         goto unsupported;
239bf215546Sopenharmony_ci      }
240bf215546Sopenharmony_ci   }
241bf215546Sopenharmony_ci
242bf215546Sopenharmony_ci   if (info->usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
243bf215546Sopenharmony_ci      if (!(format_feature_flags &
244bf215546Sopenharmony_ci            VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)) {
245bf215546Sopenharmony_ci         goto unsupported;
246bf215546Sopenharmony_ci      }
247bf215546Sopenharmony_ci   }
248bf215546Sopenharmony_ci
249bf215546Sopenharmony_ci   *pImageFormatProperties = (VkImageFormatProperties) {
250bf215546Sopenharmony_ci      .maxExtent = maxExtent,
251bf215546Sopenharmony_ci      .maxMipLevels = maxMipLevels,
252bf215546Sopenharmony_ci      .maxArrayLayers = maxArraySize,
253bf215546Sopenharmony_ci      .sampleCounts = sampleCounts,
254bf215546Sopenharmony_ci
255bf215546Sopenharmony_ci      /* FINISHME: Accurately calculate
256bf215546Sopenharmony_ci       * VkImageFormatProperties::maxResourceSize.
257bf215546Sopenharmony_ci       */
258bf215546Sopenharmony_ci      .maxResourceSize = UINT32_MAX,
259bf215546Sopenharmony_ci   };
260bf215546Sopenharmony_ci
261bf215546Sopenharmony_ci   if (p_feature_flags)
262bf215546Sopenharmony_ci      *p_feature_flags = format_feature_flags;
263bf215546Sopenharmony_ci
264bf215546Sopenharmony_ci   return VK_SUCCESS;
265bf215546Sopenharmony_ciunsupported:
266bf215546Sopenharmony_ci   *pImageFormatProperties = (VkImageFormatProperties) {
267bf215546Sopenharmony_ci      .maxExtent = { 0, 0, 0 },
268bf215546Sopenharmony_ci      .maxMipLevels = 0,
269bf215546Sopenharmony_ci      .maxArrayLayers = 0,
270bf215546Sopenharmony_ci      .sampleCounts = 0,
271bf215546Sopenharmony_ci      .maxResourceSize = 0,
272bf215546Sopenharmony_ci   };
273bf215546Sopenharmony_ci
274bf215546Sopenharmony_ci   return VK_ERROR_FORMAT_NOT_SUPPORTED;
275bf215546Sopenharmony_ci}
276bf215546Sopenharmony_ci
277bf215546Sopenharmony_ci
278bf215546Sopenharmony_ciVkResult
279bf215546Sopenharmony_cipanvk_GetPhysicalDeviceImageFormatProperties(VkPhysicalDevice physicalDevice,
280bf215546Sopenharmony_ci                                            VkFormat format,
281bf215546Sopenharmony_ci                                            VkImageType type,
282bf215546Sopenharmony_ci                                            VkImageTiling tiling,
283bf215546Sopenharmony_ci                                            VkImageUsageFlags usage,
284bf215546Sopenharmony_ci                                            VkImageCreateFlags createFlags,
285bf215546Sopenharmony_ci                                            VkImageFormatProperties *pImageFormatProperties)
286bf215546Sopenharmony_ci{
287bf215546Sopenharmony_ci   VK_FROM_HANDLE(panvk_physical_device, physical_device, physicalDevice);
288bf215546Sopenharmony_ci
289bf215546Sopenharmony_ci   const VkPhysicalDeviceImageFormatInfo2 info = {
290bf215546Sopenharmony_ci      .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
291bf215546Sopenharmony_ci      .pNext = NULL,
292bf215546Sopenharmony_ci      .format = format,
293bf215546Sopenharmony_ci      .type = type,
294bf215546Sopenharmony_ci      .tiling = tiling,
295bf215546Sopenharmony_ci      .usage = usage,
296bf215546Sopenharmony_ci      .flags = createFlags,
297bf215546Sopenharmony_ci   };
298bf215546Sopenharmony_ci
299bf215546Sopenharmony_ci   return get_image_format_properties(physical_device, &info,
300bf215546Sopenharmony_ci                                      pImageFormatProperties, NULL);
301bf215546Sopenharmony_ci}
302bf215546Sopenharmony_ci
303bf215546Sopenharmony_cistatic VkResult
304bf215546Sopenharmony_cipanvk_get_external_image_format_properties(const struct panvk_physical_device *physical_device,
305bf215546Sopenharmony_ci                                           const VkPhysicalDeviceImageFormatInfo2 *pImageFormatInfo,
306bf215546Sopenharmony_ci                                           VkExternalMemoryHandleTypeFlagBits handleType,
307bf215546Sopenharmony_ci                                           VkExternalMemoryProperties *external_properties)
308bf215546Sopenharmony_ci{
309bf215546Sopenharmony_ci   VkExternalMemoryFeatureFlagBits flags = 0;
310bf215546Sopenharmony_ci   VkExternalMemoryHandleTypeFlags export_flags = 0;
311bf215546Sopenharmony_ci   VkExternalMemoryHandleTypeFlags compat_flags = 0;
312bf215546Sopenharmony_ci
313bf215546Sopenharmony_ci   /* From the Vulkan 1.1.98 spec:
314bf215546Sopenharmony_ci    *
315bf215546Sopenharmony_ci    *    If handleType is not compatible with the format, type, tiling,
316bf215546Sopenharmony_ci    *    usage, and flags specified in VkPhysicalDeviceImageFormatInfo2,
317bf215546Sopenharmony_ci    *    then vkGetPhysicalDeviceImageFormatProperties2 returns
318bf215546Sopenharmony_ci    *    VK_ERROR_FORMAT_NOT_SUPPORTED.
319bf215546Sopenharmony_ci    */
320bf215546Sopenharmony_ci   switch (handleType) {
321bf215546Sopenharmony_ci   case VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT:
322bf215546Sopenharmony_ci   case VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT:
323bf215546Sopenharmony_ci      switch (pImageFormatInfo->type) {
324bf215546Sopenharmony_ci      case VK_IMAGE_TYPE_2D:
325bf215546Sopenharmony_ci         flags = VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT |
326bf215546Sopenharmony_ci                 VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT |
327bf215546Sopenharmony_ci                 VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT;
328bf215546Sopenharmony_ci         compat_flags = export_flags =
329bf215546Sopenharmony_ci            VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT |
330bf215546Sopenharmony_ci            VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
331bf215546Sopenharmony_ci         break;
332bf215546Sopenharmony_ci      default:
333bf215546Sopenharmony_ci         return vk_errorf(physical_device, VK_ERROR_FORMAT_NOT_SUPPORTED,
334bf215546Sopenharmony_ci                          "VkExternalMemoryTypeFlagBits(0x%x) unsupported for VkImageType(%d)",
335bf215546Sopenharmony_ci                          handleType, pImageFormatInfo->type);
336bf215546Sopenharmony_ci      }
337bf215546Sopenharmony_ci      break;
338bf215546Sopenharmony_ci   case VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT:
339bf215546Sopenharmony_ci      flags = VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT;
340bf215546Sopenharmony_ci      compat_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT;
341bf215546Sopenharmony_ci      break;
342bf215546Sopenharmony_ci   default:
343bf215546Sopenharmony_ci      return vk_errorf(physical_device, VK_ERROR_FORMAT_NOT_SUPPORTED,
344bf215546Sopenharmony_ci                       "VkExternalMemoryTypeFlagBits(0x%x) unsupported",
345bf215546Sopenharmony_ci                       handleType);
346bf215546Sopenharmony_ci   }
347bf215546Sopenharmony_ci
348bf215546Sopenharmony_ci   *external_properties = (VkExternalMemoryProperties) {
349bf215546Sopenharmony_ci      .externalMemoryFeatures = flags,
350bf215546Sopenharmony_ci      .exportFromImportedHandleTypes = export_flags,
351bf215546Sopenharmony_ci      .compatibleHandleTypes = compat_flags,
352bf215546Sopenharmony_ci   };
353bf215546Sopenharmony_ci
354bf215546Sopenharmony_ci   return VK_SUCCESS;
355bf215546Sopenharmony_ci}
356bf215546Sopenharmony_ci
357bf215546Sopenharmony_ciVkResult
358bf215546Sopenharmony_cipanvk_GetPhysicalDeviceImageFormatProperties2(VkPhysicalDevice physicalDevice,
359bf215546Sopenharmony_ci                                              const VkPhysicalDeviceImageFormatInfo2 *base_info,
360bf215546Sopenharmony_ci                                              VkImageFormatProperties2 *base_props)
361bf215546Sopenharmony_ci{
362bf215546Sopenharmony_ci   VK_FROM_HANDLE(panvk_physical_device, physical_device, physicalDevice);
363bf215546Sopenharmony_ci   const VkPhysicalDeviceExternalImageFormatInfo *external_info = NULL;
364bf215546Sopenharmony_ci   const VkPhysicalDeviceImageViewImageFormatInfoEXT *image_view_info = NULL;
365bf215546Sopenharmony_ci   VkExternalImageFormatProperties *external_props = NULL;
366bf215546Sopenharmony_ci   VkFilterCubicImageViewImageFormatPropertiesEXT *cubic_props = NULL;
367bf215546Sopenharmony_ci   VkFormatFeatureFlags format_feature_flags;
368bf215546Sopenharmony_ci   VkSamplerYcbcrConversionImageFormatProperties *ycbcr_props = NULL;
369bf215546Sopenharmony_ci   VkResult result;
370bf215546Sopenharmony_ci
371bf215546Sopenharmony_ci   result = get_image_format_properties(physical_device, base_info,
372bf215546Sopenharmony_ci                                        &base_props->imageFormatProperties,
373bf215546Sopenharmony_ci                                        &format_feature_flags);
374bf215546Sopenharmony_ci   if (result != VK_SUCCESS)
375bf215546Sopenharmony_ci      return result;
376bf215546Sopenharmony_ci
377bf215546Sopenharmony_ci   /* Extract input structs */
378bf215546Sopenharmony_ci   vk_foreach_struct_const(s, base_info->pNext)
379bf215546Sopenharmony_ci   {
380bf215546Sopenharmony_ci      switch (s->sType) {
381bf215546Sopenharmony_ci      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO:
382bf215546Sopenharmony_ci         external_info = (const void *) s;
383bf215546Sopenharmony_ci         break;
384bf215546Sopenharmony_ci      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_VIEW_IMAGE_FORMAT_INFO_EXT:
385bf215546Sopenharmony_ci         image_view_info = (const void *) s;
386bf215546Sopenharmony_ci         break;
387bf215546Sopenharmony_ci      default:
388bf215546Sopenharmony_ci         break;
389bf215546Sopenharmony_ci      }
390bf215546Sopenharmony_ci   }
391bf215546Sopenharmony_ci
392bf215546Sopenharmony_ci   /* Extract output structs */
393bf215546Sopenharmony_ci   vk_foreach_struct(s, base_props->pNext)
394bf215546Sopenharmony_ci   {
395bf215546Sopenharmony_ci      switch (s->sType) {
396bf215546Sopenharmony_ci      case VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES:
397bf215546Sopenharmony_ci         external_props = (void *) s;
398bf215546Sopenharmony_ci         break;
399bf215546Sopenharmony_ci      case VK_STRUCTURE_TYPE_FILTER_CUBIC_IMAGE_VIEW_IMAGE_FORMAT_PROPERTIES_EXT:
400bf215546Sopenharmony_ci         cubic_props = (void *) s;
401bf215546Sopenharmony_ci         break;
402bf215546Sopenharmony_ci      case VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES:
403bf215546Sopenharmony_ci         ycbcr_props = (void *) s;
404bf215546Sopenharmony_ci         break;
405bf215546Sopenharmony_ci      default:
406bf215546Sopenharmony_ci         break;
407bf215546Sopenharmony_ci      }
408bf215546Sopenharmony_ci   }
409bf215546Sopenharmony_ci
410bf215546Sopenharmony_ci   /* From the Vulkan 1.0.42 spec:
411bf215546Sopenharmony_ci    *
412bf215546Sopenharmony_ci    *    If handleType is 0, vkGetPhysicalDeviceImageFormatProperties2 will
413bf215546Sopenharmony_ci    *    behave as if VkPhysicalDeviceExternalImageFormatInfo was not
414bf215546Sopenharmony_ci    *    present and VkExternalImageFormatProperties will be ignored.
415bf215546Sopenharmony_ci    */
416bf215546Sopenharmony_ci   if (external_info && external_info->handleType != 0) {
417bf215546Sopenharmony_ci      result = panvk_get_external_image_format_properties(physical_device,
418bf215546Sopenharmony_ci                                                          base_info,
419bf215546Sopenharmony_ci                                                          external_info->handleType,
420bf215546Sopenharmony_ci                                                          &external_props->externalMemoryProperties);
421bf215546Sopenharmony_ci      if (result != VK_SUCCESS)
422bf215546Sopenharmony_ci         goto fail;
423bf215546Sopenharmony_ci   }
424bf215546Sopenharmony_ci
425bf215546Sopenharmony_ci   if (cubic_props) {
426bf215546Sopenharmony_ci      /* note: blob only allows cubic filtering for 2D and 2D array views
427bf215546Sopenharmony_ci       * its likely we can enable it for 1D and CUBE, needs testing however
428bf215546Sopenharmony_ci       */
429bf215546Sopenharmony_ci      if ((image_view_info->imageViewType == VK_IMAGE_VIEW_TYPE_2D ||
430bf215546Sopenharmony_ci           image_view_info->imageViewType == VK_IMAGE_VIEW_TYPE_2D_ARRAY) &&
431bf215546Sopenharmony_ci          (format_feature_flags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_EXT)) {
432bf215546Sopenharmony_ci         cubic_props->filterCubic = true;
433bf215546Sopenharmony_ci         cubic_props->filterCubicMinmax = true;
434bf215546Sopenharmony_ci      } else {
435bf215546Sopenharmony_ci         cubic_props->filterCubic = false;
436bf215546Sopenharmony_ci         cubic_props->filterCubicMinmax = false;
437bf215546Sopenharmony_ci      }
438bf215546Sopenharmony_ci   }
439bf215546Sopenharmony_ci
440bf215546Sopenharmony_ci   if (ycbcr_props)
441bf215546Sopenharmony_ci      ycbcr_props->combinedImageSamplerDescriptorCount = 1;
442bf215546Sopenharmony_ci
443bf215546Sopenharmony_ci   return VK_SUCCESS;
444bf215546Sopenharmony_ci
445bf215546Sopenharmony_cifail:
446bf215546Sopenharmony_ci   if (result == VK_ERROR_FORMAT_NOT_SUPPORTED) {
447bf215546Sopenharmony_ci      /* From the Vulkan 1.0.42 spec:
448bf215546Sopenharmony_ci       *
449bf215546Sopenharmony_ci       *    If the combination of parameters to
450bf215546Sopenharmony_ci       *    vkGetPhysicalDeviceImageFormatProperties2 is not supported by
451bf215546Sopenharmony_ci       *    the implementation for use in vkCreateImage, then all members of
452bf215546Sopenharmony_ci       *    imageFormatProperties will be filled with zero.
453bf215546Sopenharmony_ci       */
454bf215546Sopenharmony_ci      base_props->imageFormatProperties = (VkImageFormatProperties) {};
455bf215546Sopenharmony_ci   }
456bf215546Sopenharmony_ci
457bf215546Sopenharmony_ci   return result;
458bf215546Sopenharmony_ci}
459bf215546Sopenharmony_ci
460bf215546Sopenharmony_civoid
461bf215546Sopenharmony_cipanvk_GetPhysicalDeviceSparseImageFormatProperties(VkPhysicalDevice physicalDevice,
462bf215546Sopenharmony_ci                                                   VkFormat format,
463bf215546Sopenharmony_ci                                                   VkImageType type,
464bf215546Sopenharmony_ci                                                   uint32_t samples,
465bf215546Sopenharmony_ci                                                   VkImageUsageFlags usage,
466bf215546Sopenharmony_ci                                                   VkImageTiling tiling,
467bf215546Sopenharmony_ci                                                   uint32_t *pNumProperties,
468bf215546Sopenharmony_ci                                                   VkSparseImageFormatProperties *pProperties)
469bf215546Sopenharmony_ci{
470bf215546Sopenharmony_ci   /* Sparse images are not yet supported. */
471bf215546Sopenharmony_ci   *pNumProperties = 0;
472bf215546Sopenharmony_ci}
473bf215546Sopenharmony_ci
474bf215546Sopenharmony_civoid
475bf215546Sopenharmony_cipanvk_GetPhysicalDeviceSparseImageFormatProperties2(VkPhysicalDevice physicalDevice,
476bf215546Sopenharmony_ci                                                    const VkPhysicalDeviceSparseImageFormatInfo2 *pFormatInfo,
477bf215546Sopenharmony_ci                                                    uint32_t *pPropertyCount,
478bf215546Sopenharmony_ci                                                    VkSparseImageFormatProperties2 *pProperties)
479bf215546Sopenharmony_ci{
480bf215546Sopenharmony_ci   /* Sparse images are not yet supported. */
481bf215546Sopenharmony_ci   *pPropertyCount = 0;
482bf215546Sopenharmony_ci}
483bf215546Sopenharmony_ci
484bf215546Sopenharmony_civoid
485bf215546Sopenharmony_cipanvk_GetPhysicalDeviceExternalBufferProperties(VkPhysicalDevice physicalDevice,
486bf215546Sopenharmony_ci                                                const VkPhysicalDeviceExternalBufferInfo *pExternalBufferInfo,
487bf215546Sopenharmony_ci                                                VkExternalBufferProperties *pExternalBufferProperties)
488bf215546Sopenharmony_ci{
489bf215546Sopenharmony_ci   panvk_stub();
490bf215546Sopenharmony_ci}
491