1bf215546Sopenharmony_ci/*
2bf215546Sopenharmony_ci * Copyright © 2019 Raspberry Pi Ltd
3bf215546Sopenharmony_ci *
4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
5bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"),
6bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation
7bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the
9bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions:
10bf215546Sopenharmony_ci *
11bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next
12bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the
13bf215546Sopenharmony_ci * Software.
14bf215546Sopenharmony_ci *
15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20bf215546Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21bf215546Sopenharmony_ci * IN THE SOFTWARE.
22bf215546Sopenharmony_ci */
23bf215546Sopenharmony_ci
24bf215546Sopenharmony_ci#include "v3dv_private.h"
25bf215546Sopenharmony_ci#include "vk_util.h"
26bf215546Sopenharmony_ci#include "vk_enum_defines.h"
27bf215546Sopenharmony_ci
28bf215546Sopenharmony_ci#include "drm-uapi/drm_fourcc.h"
29bf215546Sopenharmony_ci#include "util/format/u_format.h"
30bf215546Sopenharmony_ci#include "vulkan/wsi/wsi_common.h"
31bf215546Sopenharmony_ci
32bf215546Sopenharmony_ciconst uint8_t *
33bf215546Sopenharmony_civ3dv_get_format_swizzle(struct v3dv_device *device, VkFormat f)
34bf215546Sopenharmony_ci{
35bf215546Sopenharmony_ci   const struct v3dv_format *vf = v3dv_X(device, get_format)(f);
36bf215546Sopenharmony_ci   static const uint8_t fallback[] = {0, 1, 2, 3};
37bf215546Sopenharmony_ci
38bf215546Sopenharmony_ci   if (!vf)
39bf215546Sopenharmony_ci      return fallback;
40bf215546Sopenharmony_ci
41bf215546Sopenharmony_ci   return vf->swizzle;
42bf215546Sopenharmony_ci}
43bf215546Sopenharmony_ci
44bf215546Sopenharmony_cibool
45bf215546Sopenharmony_civ3dv_format_swizzle_needs_rb_swap(const uint8_t *swizzle)
46bf215546Sopenharmony_ci{
47bf215546Sopenharmony_ci   /* Normal case */
48bf215546Sopenharmony_ci   if (swizzle[0] == PIPE_SWIZZLE_Z)
49bf215546Sopenharmony_ci      return swizzle[2] == PIPE_SWIZZLE_X;
50bf215546Sopenharmony_ci
51bf215546Sopenharmony_ci   /* Format uses reverse flag */
52bf215546Sopenharmony_ci   if (swizzle[0] == PIPE_SWIZZLE_Y)
53bf215546Sopenharmony_ci      return swizzle[2] == PIPE_SWIZZLE_W;
54bf215546Sopenharmony_ci
55bf215546Sopenharmony_ci   return false;
56bf215546Sopenharmony_ci}
57bf215546Sopenharmony_ci
58bf215546Sopenharmony_cibool
59bf215546Sopenharmony_civ3dv_format_swizzle_needs_reverse(const uint8_t *swizzle)
60bf215546Sopenharmony_ci{
61bf215546Sopenharmony_ci   /* Normal case */
62bf215546Sopenharmony_ci   if (swizzle[0] == PIPE_SWIZZLE_W &&
63bf215546Sopenharmony_ci       swizzle[1] == PIPE_SWIZZLE_Z &&
64bf215546Sopenharmony_ci       swizzle[2] == PIPE_SWIZZLE_Y &&
65bf215546Sopenharmony_ci       swizzle[3] == PIPE_SWIZZLE_X) {
66bf215546Sopenharmony_ci      return true;
67bf215546Sopenharmony_ci   }
68bf215546Sopenharmony_ci
69bf215546Sopenharmony_ci   /* Format uses RB swap flag */
70bf215546Sopenharmony_ci   if (swizzle[0] == PIPE_SWIZZLE_Y &&
71bf215546Sopenharmony_ci       swizzle[1] == PIPE_SWIZZLE_Z &&
72bf215546Sopenharmony_ci       swizzle[2] == PIPE_SWIZZLE_W &&
73bf215546Sopenharmony_ci       swizzle[3] == PIPE_SWIZZLE_X) {
74bf215546Sopenharmony_ci      return true;
75bf215546Sopenharmony_ci   }
76bf215546Sopenharmony_ci
77bf215546Sopenharmony_ci   return false;
78bf215546Sopenharmony_ci}
79bf215546Sopenharmony_ci
80bf215546Sopenharmony_ciuint8_t
81bf215546Sopenharmony_civ3dv_get_tex_return_size(const struct v3dv_format *vf,
82bf215546Sopenharmony_ci                         bool compare_enable)
83bf215546Sopenharmony_ci{
84bf215546Sopenharmony_ci   if (unlikely(V3D_DEBUG & V3D_DEBUG_TMU_16BIT))
85bf215546Sopenharmony_ci      return 16;
86bf215546Sopenharmony_ci
87bf215546Sopenharmony_ci   if (unlikely(V3D_DEBUG & V3D_DEBUG_TMU_32BIT))
88bf215546Sopenharmony_ci      return 32;
89bf215546Sopenharmony_ci
90bf215546Sopenharmony_ci   if (compare_enable)
91bf215546Sopenharmony_ci      return 16;
92bf215546Sopenharmony_ci
93bf215546Sopenharmony_ci   return vf->return_size;
94bf215546Sopenharmony_ci}
95bf215546Sopenharmony_ci
96bf215546Sopenharmony_ci/* Some cases of transfer operations are raw data copies that don't depend
97bf215546Sopenharmony_ci * on the semantics of the pixel format (no pixel format conversions are
98bf215546Sopenharmony_ci * involved). In these cases, it is safe to choose any format supported by
99bf215546Sopenharmony_ci * the TFU so long as it has the same texel size, which allows us to use the
100bf215546Sopenharmony_ci * TFU paths with formats that are not TFU supported otherwise.
101bf215546Sopenharmony_ci */
102bf215546Sopenharmony_ciconst struct v3dv_format *
103bf215546Sopenharmony_civ3dv_get_compatible_tfu_format(struct v3dv_device *device,
104bf215546Sopenharmony_ci                               uint32_t bpp,
105bf215546Sopenharmony_ci                               VkFormat *out_vk_format)
106bf215546Sopenharmony_ci{
107bf215546Sopenharmony_ci   VkFormat vk_format;
108bf215546Sopenharmony_ci   switch (bpp) {
109bf215546Sopenharmony_ci   case 16: vk_format = VK_FORMAT_R32G32B32A32_SFLOAT;  break;
110bf215546Sopenharmony_ci   case 8:  vk_format = VK_FORMAT_R16G16B16A16_SFLOAT;  break;
111bf215546Sopenharmony_ci   case 4:  vk_format = VK_FORMAT_R32_SFLOAT;           break;
112bf215546Sopenharmony_ci   case 2:  vk_format = VK_FORMAT_R16_SFLOAT;           break;
113bf215546Sopenharmony_ci   case 1:  vk_format = VK_FORMAT_R8_UNORM;             break;
114bf215546Sopenharmony_ci   default: unreachable("unsupported format bit-size"); break;
115bf215546Sopenharmony_ci   };
116bf215546Sopenharmony_ci
117bf215546Sopenharmony_ci   if (out_vk_format)
118bf215546Sopenharmony_ci      *out_vk_format = vk_format;
119bf215546Sopenharmony_ci
120bf215546Sopenharmony_ci   const struct v3dv_format *format = v3dv_X(device, get_format)(vk_format);
121bf215546Sopenharmony_ci   assert(v3dv_X(device, tfu_supports_tex_format)(format->tex_type));
122bf215546Sopenharmony_ci
123bf215546Sopenharmony_ci   return format;
124bf215546Sopenharmony_ci}
125bf215546Sopenharmony_ci
126bf215546Sopenharmony_cistatic VkFormatFeatureFlags2
127bf215546Sopenharmony_ciimage_format_features(struct v3dv_physical_device *pdevice,
128bf215546Sopenharmony_ci                      VkFormat vk_format,
129bf215546Sopenharmony_ci                      const struct v3dv_format *v3dv_format,
130bf215546Sopenharmony_ci                      VkImageTiling tiling)
131bf215546Sopenharmony_ci{
132bf215546Sopenharmony_ci   if (!v3dv_format || !v3dv_format->supported)
133bf215546Sopenharmony_ci      return 0;
134bf215546Sopenharmony_ci
135bf215546Sopenharmony_ci   const VkImageAspectFlags aspects = vk_format_aspects(vk_format);
136bf215546Sopenharmony_ci
137bf215546Sopenharmony_ci   const VkImageAspectFlags zs_aspects = VK_IMAGE_ASPECT_DEPTH_BIT |
138bf215546Sopenharmony_ci                                         VK_IMAGE_ASPECT_STENCIL_BIT;
139bf215546Sopenharmony_ci   const VkImageAspectFlags supported_aspects = VK_IMAGE_ASPECT_COLOR_BIT |
140bf215546Sopenharmony_ci                                                zs_aspects;
141bf215546Sopenharmony_ci   if ((aspects & supported_aspects) != aspects)
142bf215546Sopenharmony_ci      return 0;
143bf215546Sopenharmony_ci
144bf215546Sopenharmony_ci   /* FIXME: We don't support separate stencil yet */
145bf215546Sopenharmony_ci   if ((aspects & zs_aspects) == VK_IMAGE_ASPECT_STENCIL_BIT)
146bf215546Sopenharmony_ci      return 0;
147bf215546Sopenharmony_ci
148bf215546Sopenharmony_ci   if (v3dv_format->tex_type == TEXTURE_DATA_FORMAT_NO &&
149bf215546Sopenharmony_ci       v3dv_format->rt_type == V3D_OUTPUT_IMAGE_FORMAT_NO) {
150bf215546Sopenharmony_ci      return 0;
151bf215546Sopenharmony_ci   }
152bf215546Sopenharmony_ci
153bf215546Sopenharmony_ci   VkFormatFeatureFlags2 flags = 0;
154bf215546Sopenharmony_ci
155bf215546Sopenharmony_ci   /* Raster format is only supported for 1D textures, so let's just
156bf215546Sopenharmony_ci    * always require optimal tiling for anything that requires sampling.
157bf215546Sopenharmony_ci    * Note: even if the user requests optimal for a 1D image, we will still
158bf215546Sopenharmony_ci    * use raster format since that is what the HW requires.
159bf215546Sopenharmony_ci    */
160bf215546Sopenharmony_ci   if (v3dv_format->tex_type != TEXTURE_DATA_FORMAT_NO &&
161bf215546Sopenharmony_ci       tiling == VK_IMAGE_TILING_OPTIMAL) {
162bf215546Sopenharmony_ci      flags |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT |
163bf215546Sopenharmony_ci               VK_FORMAT_FEATURE_2_BLIT_SRC_BIT;
164bf215546Sopenharmony_ci
165bf215546Sopenharmony_ci      if (v3dv_format->supports_filtering)
166bf215546Sopenharmony_ci         flags |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_LINEAR_BIT;
167bf215546Sopenharmony_ci   }
168bf215546Sopenharmony_ci
169bf215546Sopenharmony_ci   if (v3dv_format->rt_type != V3D_OUTPUT_IMAGE_FORMAT_NO) {
170bf215546Sopenharmony_ci      if (aspects & VK_IMAGE_ASPECT_COLOR_BIT) {
171bf215546Sopenharmony_ci         flags |= VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT |
172bf215546Sopenharmony_ci                  VK_FORMAT_FEATURE_2_BLIT_DST_BIT;
173bf215546Sopenharmony_ci         if (v3dv_X(pdevice, format_supports_blending)(v3dv_format))
174bf215546Sopenharmony_ci            flags |= VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BLEND_BIT;
175bf215546Sopenharmony_ci      } else if (aspects & zs_aspects) {
176bf215546Sopenharmony_ci         flags |= VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT |
177bf215546Sopenharmony_ci                  VK_FORMAT_FEATURE_2_BLIT_DST_BIT;
178bf215546Sopenharmony_ci      }
179bf215546Sopenharmony_ci   }
180bf215546Sopenharmony_ci
181bf215546Sopenharmony_ci   const struct util_format_description *desc =
182bf215546Sopenharmony_ci      vk_format_description(vk_format);
183bf215546Sopenharmony_ci
184bf215546Sopenharmony_ci   if (tiling != VK_IMAGE_TILING_LINEAR) {
185bf215546Sopenharmony_ci      if (desc->layout == UTIL_FORMAT_LAYOUT_PLAIN && desc->is_array) {
186bf215546Sopenharmony_ci         flags |= VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT;
187bf215546Sopenharmony_ci         if (desc->nr_channels == 1 && vk_format_is_int(vk_format))
188bf215546Sopenharmony_ci            flags |= VK_FORMAT_FEATURE_2_STORAGE_IMAGE_ATOMIC_BIT;
189bf215546Sopenharmony_ci      } else if (vk_format == VK_FORMAT_A2B10G10R10_UNORM_PACK32 ||
190bf215546Sopenharmony_ci                 vk_format == VK_FORMAT_A2B10G10R10_UINT_PACK32 ||
191bf215546Sopenharmony_ci                 vk_format == VK_FORMAT_B10G11R11_UFLOAT_PACK32) {
192bf215546Sopenharmony_ci         /* To comply with shaderStorageImageExtendedFormats */
193bf215546Sopenharmony_ci         flags |= VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT;
194bf215546Sopenharmony_ci      }
195bf215546Sopenharmony_ci   }
196bf215546Sopenharmony_ci
197bf215546Sopenharmony_ci   /* All our depth formats support shadow comparisons. */
198bf215546Sopenharmony_ci   if (vk_format_has_depth(vk_format) &&
199bf215546Sopenharmony_ci       (flags & VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT)) {
200bf215546Sopenharmony_ci      flags |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_DEPTH_COMPARISON_BIT;
201bf215546Sopenharmony_ci   }
202bf215546Sopenharmony_ci
203bf215546Sopenharmony_ci   if (flags) {
204bf215546Sopenharmony_ci      flags |= VK_FORMAT_FEATURE_2_TRANSFER_SRC_BIT |
205bf215546Sopenharmony_ci               VK_FORMAT_FEATURE_2_TRANSFER_DST_BIT;
206bf215546Sopenharmony_ci   }
207bf215546Sopenharmony_ci
208bf215546Sopenharmony_ci   return flags;
209bf215546Sopenharmony_ci}
210bf215546Sopenharmony_ci
211bf215546Sopenharmony_cistatic VkFormatFeatureFlags2
212bf215546Sopenharmony_cibuffer_format_features(VkFormat vk_format, const struct v3dv_format *v3dv_format)
213bf215546Sopenharmony_ci{
214bf215546Sopenharmony_ci   if (!v3dv_format || !v3dv_format->supported)
215bf215546Sopenharmony_ci      return 0;
216bf215546Sopenharmony_ci
217bf215546Sopenharmony_ci   if (!v3dv_format->supported)
218bf215546Sopenharmony_ci      return 0;
219bf215546Sopenharmony_ci
220bf215546Sopenharmony_ci   /* We probably only want to support buffer formats that have a
221bf215546Sopenharmony_ci    * color format specification.
222bf215546Sopenharmony_ci    */
223bf215546Sopenharmony_ci   if (!vk_format_is_color(vk_format))
224bf215546Sopenharmony_ci      return 0;
225bf215546Sopenharmony_ci
226bf215546Sopenharmony_ci   const struct util_format_description *desc =
227bf215546Sopenharmony_ci      vk_format_description(vk_format);
228bf215546Sopenharmony_ci
229bf215546Sopenharmony_ci   VkFormatFeatureFlags2 flags = 0;
230bf215546Sopenharmony_ci   if (desc->layout == UTIL_FORMAT_LAYOUT_PLAIN &&
231bf215546Sopenharmony_ci       desc->colorspace == UTIL_FORMAT_COLORSPACE_RGB &&
232bf215546Sopenharmony_ci       desc->is_array) {
233bf215546Sopenharmony_ci      flags |=  VK_FORMAT_FEATURE_2_VERTEX_BUFFER_BIT;
234bf215546Sopenharmony_ci      if (v3dv_format->tex_type != TEXTURE_DATA_FORMAT_NO) {
235bf215546Sopenharmony_ci         flags |= VK_FORMAT_FEATURE_2_UNIFORM_TEXEL_BUFFER_BIT |
236bf215546Sopenharmony_ci                  VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_BIT;
237bf215546Sopenharmony_ci      }
238bf215546Sopenharmony_ci   } else if (vk_format == VK_FORMAT_A2B10G10R10_UNORM_PACK32) {
239bf215546Sopenharmony_ci      flags |= VK_FORMAT_FEATURE_2_VERTEX_BUFFER_BIT |
240bf215546Sopenharmony_ci               VK_FORMAT_FEATURE_2_UNIFORM_TEXEL_BUFFER_BIT |
241bf215546Sopenharmony_ci               VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_BIT;
242bf215546Sopenharmony_ci   } else if (vk_format == VK_FORMAT_A2B10G10R10_UINT_PACK32 ||
243bf215546Sopenharmony_ci              vk_format == VK_FORMAT_B10G11R11_UFLOAT_PACK32) {
244bf215546Sopenharmony_ci      flags |= VK_FORMAT_FEATURE_2_UNIFORM_TEXEL_BUFFER_BIT |
245bf215546Sopenharmony_ci               VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_BIT;
246bf215546Sopenharmony_ci   }
247bf215546Sopenharmony_ci
248bf215546Sopenharmony_ci   if (desc->layout == UTIL_FORMAT_LAYOUT_PLAIN &&
249bf215546Sopenharmony_ci       desc->is_array &&
250bf215546Sopenharmony_ci       desc->nr_channels == 1 &&
251bf215546Sopenharmony_ci       vk_format_is_int(vk_format)) {
252bf215546Sopenharmony_ci      flags |= VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_ATOMIC_BIT;
253bf215546Sopenharmony_ci   }
254bf215546Sopenharmony_ci
255bf215546Sopenharmony_ci   return flags;
256bf215546Sopenharmony_ci}
257bf215546Sopenharmony_ci
258bf215546Sopenharmony_cibool
259bf215546Sopenharmony_civ3dv_buffer_format_supports_features(struct v3dv_device *device,
260bf215546Sopenharmony_ci                                     VkFormat vk_format,
261bf215546Sopenharmony_ci                                     VkFormatFeatureFlags2 features)
262bf215546Sopenharmony_ci{
263bf215546Sopenharmony_ci   const struct v3dv_format *v3dv_format = v3dv_X(device, get_format)(vk_format);
264bf215546Sopenharmony_ci   const VkFormatFeatureFlags2 supported =
265bf215546Sopenharmony_ci      buffer_format_features(vk_format, v3dv_format);
266bf215546Sopenharmony_ci   return (supported & features) == features;
267bf215546Sopenharmony_ci}
268bf215546Sopenharmony_ci
269bf215546Sopenharmony_ci/* FIXME: this helper now on anv, radv, lvp, and v3dv. Perhaps common
270bf215546Sopenharmony_ci * place?
271bf215546Sopenharmony_ci */
272bf215546Sopenharmony_cistatic inline VkFormatFeatureFlags
273bf215546Sopenharmony_cifeatures2_to_features(VkFormatFeatureFlags2 features2)
274bf215546Sopenharmony_ci{
275bf215546Sopenharmony_ci   return features2 & VK_ALL_FORMAT_FEATURE_FLAG_BITS;
276bf215546Sopenharmony_ci}
277bf215546Sopenharmony_ci
278bf215546Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL
279bf215546Sopenharmony_civ3dv_GetPhysicalDeviceFormatProperties2(VkPhysicalDevice physicalDevice,
280bf215546Sopenharmony_ci                                        VkFormat format,
281bf215546Sopenharmony_ci                                        VkFormatProperties2 *pFormatProperties)
282bf215546Sopenharmony_ci{
283bf215546Sopenharmony_ci   V3DV_FROM_HANDLE(v3dv_physical_device, pdevice, physicalDevice);
284bf215546Sopenharmony_ci   const struct v3dv_format *v3dv_format = v3dv_X(pdevice, get_format)(format);
285bf215546Sopenharmony_ci
286bf215546Sopenharmony_ci   VkFormatFeatureFlags2 linear2, optimal2, buffer2;
287bf215546Sopenharmony_ci   linear2 = image_format_features(pdevice, format, v3dv_format,
288bf215546Sopenharmony_ci                                   VK_IMAGE_TILING_LINEAR);
289bf215546Sopenharmony_ci   optimal2 = image_format_features(pdevice, format, v3dv_format,
290bf215546Sopenharmony_ci                                    VK_IMAGE_TILING_OPTIMAL);
291bf215546Sopenharmony_ci   buffer2 = buffer_format_features(format, v3dv_format);
292bf215546Sopenharmony_ci   pFormatProperties->formatProperties = (VkFormatProperties) {
293bf215546Sopenharmony_ci      .linearTilingFeatures = features2_to_features(linear2),
294bf215546Sopenharmony_ci      .optimalTilingFeatures = features2_to_features(optimal2),
295bf215546Sopenharmony_ci      .bufferFeatures = features2_to_features(buffer2),
296bf215546Sopenharmony_ci   };
297bf215546Sopenharmony_ci
298bf215546Sopenharmony_ci   vk_foreach_struct(ext, pFormatProperties->pNext) {
299bf215546Sopenharmony_ci      switch ((unsigned)ext->sType) {
300bf215546Sopenharmony_ci      case VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT: {
301bf215546Sopenharmony_ci         struct VkDrmFormatModifierPropertiesListEXT *list = (void *)ext;
302bf215546Sopenharmony_ci         VK_OUTARRAY_MAKE_TYPED(VkDrmFormatModifierPropertiesEXT, out,
303bf215546Sopenharmony_ci                                list->pDrmFormatModifierProperties,
304bf215546Sopenharmony_ci                                &list->drmFormatModifierCount);
305bf215546Sopenharmony_ci         if (pFormatProperties->formatProperties.linearTilingFeatures) {
306bf215546Sopenharmony_ci            vk_outarray_append_typed(VkDrmFormatModifierPropertiesEXT,
307bf215546Sopenharmony_ci                                     &out, mod_props) {
308bf215546Sopenharmony_ci               mod_props->drmFormatModifier = DRM_FORMAT_MOD_LINEAR;
309bf215546Sopenharmony_ci               mod_props->drmFormatModifierPlaneCount = 1;
310bf215546Sopenharmony_ci               mod_props->drmFormatModifierTilingFeatures =
311bf215546Sopenharmony_ci                  pFormatProperties->formatProperties.linearTilingFeatures;
312bf215546Sopenharmony_ci            }
313bf215546Sopenharmony_ci         }
314bf215546Sopenharmony_ci         if (pFormatProperties->formatProperties.optimalTilingFeatures) {
315bf215546Sopenharmony_ci            vk_outarray_append_typed(VkDrmFormatModifierPropertiesEXT,
316bf215546Sopenharmony_ci                                     &out, mod_props) {
317bf215546Sopenharmony_ci               mod_props->drmFormatModifier = DRM_FORMAT_MOD_BROADCOM_UIF;
318bf215546Sopenharmony_ci               mod_props->drmFormatModifierPlaneCount = 1;
319bf215546Sopenharmony_ci               mod_props->drmFormatModifierTilingFeatures =
320bf215546Sopenharmony_ci                  pFormatProperties->formatProperties.optimalTilingFeatures;
321bf215546Sopenharmony_ci            }
322bf215546Sopenharmony_ci         }
323bf215546Sopenharmony_ci         break;
324bf215546Sopenharmony_ci      }
325bf215546Sopenharmony_ci      case VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_2_EXT: {
326bf215546Sopenharmony_ci         struct VkDrmFormatModifierPropertiesList2EXT *list = (void *)ext;
327bf215546Sopenharmony_ci         VK_OUTARRAY_MAKE_TYPED(VkDrmFormatModifierProperties2EXT, out,
328bf215546Sopenharmony_ci                                list->pDrmFormatModifierProperties,
329bf215546Sopenharmony_ci                                &list->drmFormatModifierCount);
330bf215546Sopenharmony_ci         if (linear2) {
331bf215546Sopenharmony_ci            vk_outarray_append_typed(VkDrmFormatModifierProperties2EXT,
332bf215546Sopenharmony_ci                                     &out, mod_props) {
333bf215546Sopenharmony_ci               mod_props->drmFormatModifier = DRM_FORMAT_MOD_LINEAR;
334bf215546Sopenharmony_ci               mod_props->drmFormatModifierPlaneCount = 1;
335bf215546Sopenharmony_ci               mod_props->drmFormatModifierTilingFeatures = linear2;
336bf215546Sopenharmony_ci            }
337bf215546Sopenharmony_ci         }
338bf215546Sopenharmony_ci         if (optimal2) {
339bf215546Sopenharmony_ci            vk_outarray_append_typed(VkDrmFormatModifierProperties2EXT,
340bf215546Sopenharmony_ci                                     &out, mod_props) {
341bf215546Sopenharmony_ci               mod_props->drmFormatModifier = DRM_FORMAT_MOD_BROADCOM_UIF;
342bf215546Sopenharmony_ci               mod_props->drmFormatModifierPlaneCount = 1;
343bf215546Sopenharmony_ci               mod_props->drmFormatModifierTilingFeatures = optimal2;
344bf215546Sopenharmony_ci            }
345bf215546Sopenharmony_ci         }
346bf215546Sopenharmony_ci         break;
347bf215546Sopenharmony_ci      }
348bf215546Sopenharmony_ci      case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3: {
349bf215546Sopenharmony_ci         VkFormatProperties3 *props = (VkFormatProperties3 *)ext;
350bf215546Sopenharmony_ci         props->linearTilingFeatures = linear2;
351bf215546Sopenharmony_ci         props->optimalTilingFeatures = optimal2;
352bf215546Sopenharmony_ci         props->bufferFeatures = buffer2;
353bf215546Sopenharmony_ci         break;
354bf215546Sopenharmony_ci      }
355bf215546Sopenharmony_ci      default:
356bf215546Sopenharmony_ci         v3dv_debug_ignored_stype(ext->sType);
357bf215546Sopenharmony_ci         break;
358bf215546Sopenharmony_ci      }
359bf215546Sopenharmony_ci   }
360bf215546Sopenharmony_ci}
361bf215546Sopenharmony_ci
362bf215546Sopenharmony_cistatic VkResult
363bf215546Sopenharmony_ciget_image_format_properties(
364bf215546Sopenharmony_ci   struct v3dv_physical_device *physical_device,
365bf215546Sopenharmony_ci   const VkPhysicalDeviceImageFormatInfo2 *info,
366bf215546Sopenharmony_ci   VkImageTiling tiling,
367bf215546Sopenharmony_ci   VkImageFormatProperties *pImageFormatProperties,
368bf215546Sopenharmony_ci   VkSamplerYcbcrConversionImageFormatProperties *pYcbcrImageFormatProperties)
369bf215546Sopenharmony_ci{
370bf215546Sopenharmony_ci   const struct v3dv_format *v3dv_format = v3dv_X(physical_device, get_format)(info->format);
371bf215546Sopenharmony_ci   VkFormatFeatureFlags2 format_feature_flags =
372bf215546Sopenharmony_ci      image_format_features(physical_device, info->format, v3dv_format, tiling);
373bf215546Sopenharmony_ci   if (!format_feature_flags)
374bf215546Sopenharmony_ci      goto unsupported;
375bf215546Sopenharmony_ci
376bf215546Sopenharmony_ci   /* This allows users to create uncompressed views of compressed images,
377bf215546Sopenharmony_ci    * however this is not something the hardware supports naturally and requires
378bf215546Sopenharmony_ci    * the driver to lie when programming the texture state to make the hardware
379bf215546Sopenharmony_ci    * sample with the uncompressed view correctly, and even then, there are
380bf215546Sopenharmony_ci    * issues when running on real hardware.
381bf215546Sopenharmony_ci    *
382bf215546Sopenharmony_ci    * See https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11336
383bf215546Sopenharmony_ci    * for details.
384bf215546Sopenharmony_ci    */
385bf215546Sopenharmony_ci   if (info->flags & VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT)
386bf215546Sopenharmony_ci      goto unsupported;
387bf215546Sopenharmony_ci
388bf215546Sopenharmony_ci   const VkImageStencilUsageCreateInfo *stencil_usage_info =
389bf215546Sopenharmony_ci      vk_find_struct_const(info->pNext, IMAGE_STENCIL_USAGE_CREATE_INFO);
390bf215546Sopenharmony_ci
391bf215546Sopenharmony_ci   VkImageUsageFlags image_usage =
392bf215546Sopenharmony_ci      info->usage | (stencil_usage_info ? stencil_usage_info->stencilUsage : 0);
393bf215546Sopenharmony_ci
394bf215546Sopenharmony_ci   /* If VK_IMAGE_CREATE_EXTENDED_USAGE_BIT is set it means the usage flags may
395bf215546Sopenharmony_ci    * not be be supported for the image format but are supported for at least
396bf215546Sopenharmony_ci    * one compatible format from which an image view can be created for the
397bf215546Sopenharmony_ci    * image. This means we should not report the format as unsupported based
398bf215546Sopenharmony_ci    * on the usage flags when usage refers to how an image view may be used
399bf215546Sopenharmony_ci    * (i.e. as a framebuffer attachment, for sampling, etc).
400bf215546Sopenharmony_ci    */
401bf215546Sopenharmony_ci   VkImageUsageFlags view_usage =
402bf215546Sopenharmony_ci      info->flags & VK_IMAGE_CREATE_EXTENDED_USAGE_BIT ? 0 : image_usage;
403bf215546Sopenharmony_ci
404bf215546Sopenharmony_ci   if (image_usage & VK_IMAGE_USAGE_TRANSFER_SRC_BIT) {
405bf215546Sopenharmony_ci      if (!(format_feature_flags & VK_FORMAT_FEATURE_2_TRANSFER_SRC_BIT)) {
406bf215546Sopenharmony_ci         goto unsupported;
407bf215546Sopenharmony_ci      }
408bf215546Sopenharmony_ci
409bf215546Sopenharmony_ci      /* Sampling of raster depth/stencil images is not supported. Since 1D
410bf215546Sopenharmony_ci       * images are always raster, even if the user requested optimal tiling,
411bf215546Sopenharmony_ci       * we can't have them be used as transfer sources, since that includes
412bf215546Sopenharmony_ci       * using them for blit sources, which might require sampling.
413bf215546Sopenharmony_ci       */
414bf215546Sopenharmony_ci      if (info->type == VK_IMAGE_TYPE_1D &&
415bf215546Sopenharmony_ci          vk_format_is_depth_or_stencil(info->format)) {
416bf215546Sopenharmony_ci         goto unsupported;
417bf215546Sopenharmony_ci      }
418bf215546Sopenharmony_ci   }
419bf215546Sopenharmony_ci
420bf215546Sopenharmony_ci   if (image_usage & VK_IMAGE_USAGE_TRANSFER_DST_BIT) {
421bf215546Sopenharmony_ci      if (!(format_feature_flags & VK_FORMAT_FEATURE_2_TRANSFER_DST_BIT)) {
422bf215546Sopenharmony_ci         goto unsupported;
423bf215546Sopenharmony_ci      }
424bf215546Sopenharmony_ci   }
425bf215546Sopenharmony_ci
426bf215546Sopenharmony_ci   if (view_usage & (VK_IMAGE_USAGE_SAMPLED_BIT |
427bf215546Sopenharmony_ci                     VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)) {
428bf215546Sopenharmony_ci      if (!(format_feature_flags & VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT)) {
429bf215546Sopenharmony_ci         goto unsupported;
430bf215546Sopenharmony_ci      }
431bf215546Sopenharmony_ci
432bf215546Sopenharmony_ci      /* Sampling of raster depth/stencil images is not supported. Since 1D
433bf215546Sopenharmony_ci       * images are always raster, even if the user requested optimal tiling,
434bf215546Sopenharmony_ci       * we can't allow sampling if the format is depth/stencil.
435bf215546Sopenharmony_ci       */
436bf215546Sopenharmony_ci      if (info->type == VK_IMAGE_TYPE_1D &&
437bf215546Sopenharmony_ci          vk_format_is_depth_or_stencil(info->format)) {
438bf215546Sopenharmony_ci         goto unsupported;
439bf215546Sopenharmony_ci      }
440bf215546Sopenharmony_ci   }
441bf215546Sopenharmony_ci
442bf215546Sopenharmony_ci   if (view_usage & VK_IMAGE_USAGE_STORAGE_BIT) {
443bf215546Sopenharmony_ci      if (!(format_feature_flags & VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT)) {
444bf215546Sopenharmony_ci         goto unsupported;
445bf215546Sopenharmony_ci      }
446bf215546Sopenharmony_ci   }
447bf215546Sopenharmony_ci
448bf215546Sopenharmony_ci   if (view_usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) {
449bf215546Sopenharmony_ci      if (!(format_feature_flags & VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT)) {
450bf215546Sopenharmony_ci         goto unsupported;
451bf215546Sopenharmony_ci      }
452bf215546Sopenharmony_ci   }
453bf215546Sopenharmony_ci
454bf215546Sopenharmony_ci   if (view_usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
455bf215546Sopenharmony_ci      if (!(format_feature_flags &
456bf215546Sopenharmony_ci            VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT)) {
457bf215546Sopenharmony_ci         goto unsupported;
458bf215546Sopenharmony_ci      }
459bf215546Sopenharmony_ci   }
460bf215546Sopenharmony_ci
461bf215546Sopenharmony_ci   switch (info->type) {
462bf215546Sopenharmony_ci   case VK_IMAGE_TYPE_1D:
463bf215546Sopenharmony_ci      pImageFormatProperties->maxExtent.width = V3D_MAX_IMAGE_DIMENSION;
464bf215546Sopenharmony_ci      pImageFormatProperties->maxExtent.height = 1;
465bf215546Sopenharmony_ci      pImageFormatProperties->maxExtent.depth = 1;
466bf215546Sopenharmony_ci      pImageFormatProperties->maxArrayLayers = V3D_MAX_ARRAY_LAYERS;
467bf215546Sopenharmony_ci      pImageFormatProperties->maxMipLevels = V3D_MAX_MIP_LEVELS;
468bf215546Sopenharmony_ci      break;
469bf215546Sopenharmony_ci   case VK_IMAGE_TYPE_2D:
470bf215546Sopenharmony_ci      pImageFormatProperties->maxExtent.width = V3D_MAX_IMAGE_DIMENSION;
471bf215546Sopenharmony_ci      pImageFormatProperties->maxExtent.height = V3D_MAX_IMAGE_DIMENSION;
472bf215546Sopenharmony_ci      pImageFormatProperties->maxExtent.depth = 1;
473bf215546Sopenharmony_ci      pImageFormatProperties->maxArrayLayers = V3D_MAX_ARRAY_LAYERS;
474bf215546Sopenharmony_ci      pImageFormatProperties->maxMipLevels = V3D_MAX_MIP_LEVELS;
475bf215546Sopenharmony_ci      break;
476bf215546Sopenharmony_ci   case VK_IMAGE_TYPE_3D:
477bf215546Sopenharmony_ci      pImageFormatProperties->maxExtent.width = V3D_MAX_IMAGE_DIMENSION;
478bf215546Sopenharmony_ci      pImageFormatProperties->maxExtent.height = V3D_MAX_IMAGE_DIMENSION;
479bf215546Sopenharmony_ci      pImageFormatProperties->maxExtent.depth = V3D_MAX_IMAGE_DIMENSION;
480bf215546Sopenharmony_ci      pImageFormatProperties->maxArrayLayers = 1;
481bf215546Sopenharmony_ci      pImageFormatProperties->maxMipLevels = V3D_MAX_MIP_LEVELS;
482bf215546Sopenharmony_ci      break;
483bf215546Sopenharmony_ci   default:
484bf215546Sopenharmony_ci      unreachable("bad VkImageType");
485bf215546Sopenharmony_ci   }
486bf215546Sopenharmony_ci
487bf215546Sopenharmony_ci   /* Our hw doesn't support 1D compressed textures. */
488bf215546Sopenharmony_ci   if (info->type == VK_IMAGE_TYPE_1D &&
489bf215546Sopenharmony_ci       vk_format_is_compressed(info->format)) {
490bf215546Sopenharmony_ci       goto unsupported;
491bf215546Sopenharmony_ci   }
492bf215546Sopenharmony_ci
493bf215546Sopenharmony_ci   /* From the Vulkan 1.0 spec, section 34.1.1. Supported Sample Counts:
494bf215546Sopenharmony_ci    *
495bf215546Sopenharmony_ci    * sampleCounts will be set to VK_SAMPLE_COUNT_1_BIT if at least one of the
496bf215546Sopenharmony_ci    * following conditions is true:
497bf215546Sopenharmony_ci    *
498bf215546Sopenharmony_ci    *   - tiling is VK_IMAGE_TILING_LINEAR
499bf215546Sopenharmony_ci    *   - type is not VK_IMAGE_TYPE_2D
500bf215546Sopenharmony_ci    *   - flags contains VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT
501bf215546Sopenharmony_ci    *   - neither the VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT flag nor the
502bf215546Sopenharmony_ci    *     VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT flag in
503bf215546Sopenharmony_ci    *     VkFormatProperties::optimalTilingFeatures returned by
504bf215546Sopenharmony_ci    *     vkGetPhysicalDeviceFormatProperties is set.
505bf215546Sopenharmony_ci    */
506bf215546Sopenharmony_ci   pImageFormatProperties->sampleCounts = VK_SAMPLE_COUNT_1_BIT;
507bf215546Sopenharmony_ci   if (tiling != VK_IMAGE_TILING_LINEAR &&
508bf215546Sopenharmony_ci       info->type == VK_IMAGE_TYPE_2D &&
509bf215546Sopenharmony_ci       !(info->flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) &&
510bf215546Sopenharmony_ci       (format_feature_flags & VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT ||
511bf215546Sopenharmony_ci        format_feature_flags & VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT)) {
512bf215546Sopenharmony_ci      pImageFormatProperties->sampleCounts |= VK_SAMPLE_COUNT_4_BIT;
513bf215546Sopenharmony_ci   }
514bf215546Sopenharmony_ci
515bf215546Sopenharmony_ci   if (tiling == VK_IMAGE_TILING_LINEAR)
516bf215546Sopenharmony_ci      pImageFormatProperties->maxMipLevels = 1;
517bf215546Sopenharmony_ci
518bf215546Sopenharmony_ci   pImageFormatProperties->maxResourceSize = 0xffffffff; /* 32-bit allocation */
519bf215546Sopenharmony_ci
520bf215546Sopenharmony_ci   return VK_SUCCESS;
521bf215546Sopenharmony_ci
522bf215546Sopenharmony_ciunsupported:
523bf215546Sopenharmony_ci   *pImageFormatProperties = (VkImageFormatProperties) {
524bf215546Sopenharmony_ci      .maxExtent = { 0, 0, 0 },
525bf215546Sopenharmony_ci      .maxMipLevels = 0,
526bf215546Sopenharmony_ci      .maxArrayLayers = 0,
527bf215546Sopenharmony_ci      .sampleCounts = 0,
528bf215546Sopenharmony_ci      .maxResourceSize = 0,
529bf215546Sopenharmony_ci   };
530bf215546Sopenharmony_ci
531bf215546Sopenharmony_ci   return VK_ERROR_FORMAT_NOT_SUPPORTED;
532bf215546Sopenharmony_ci}
533bf215546Sopenharmony_ci
534bf215546Sopenharmony_cistatic const VkExternalMemoryProperties prime_fd_props = {
535bf215546Sopenharmony_ci   .externalMemoryFeatures = VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT |
536bf215546Sopenharmony_ci                             VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT,
537bf215546Sopenharmony_ci   .exportFromImportedHandleTypes =
538bf215546Sopenharmony_ci      VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT |
539bf215546Sopenharmony_ci      VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,
540bf215546Sopenharmony_ci   .compatibleHandleTypes =
541bf215546Sopenharmony_ci      VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT |
542bf215546Sopenharmony_ci      VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,
543bf215546Sopenharmony_ci};
544bf215546Sopenharmony_ci
545bf215546Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL
546bf215546Sopenharmony_civ3dv_GetPhysicalDeviceImageFormatProperties(
547bf215546Sopenharmony_ci   VkPhysicalDevice physicalDevice,
548bf215546Sopenharmony_ci   VkFormat format,
549bf215546Sopenharmony_ci   VkImageType type,
550bf215546Sopenharmony_ci   VkImageTiling tiling,
551bf215546Sopenharmony_ci   VkImageUsageFlags usage,
552bf215546Sopenharmony_ci   VkImageCreateFlags createFlags,
553bf215546Sopenharmony_ci   VkImageFormatProperties *pImageFormatProperties)
554bf215546Sopenharmony_ci{
555bf215546Sopenharmony_ci   V3DV_FROM_HANDLE(v3dv_physical_device, physical_device, physicalDevice);
556bf215546Sopenharmony_ci
557bf215546Sopenharmony_ci   const VkPhysicalDeviceImageFormatInfo2 info = {
558bf215546Sopenharmony_ci      .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
559bf215546Sopenharmony_ci      .pNext = NULL,
560bf215546Sopenharmony_ci      .format = format,
561bf215546Sopenharmony_ci      .type = type,
562bf215546Sopenharmony_ci      .tiling = tiling,
563bf215546Sopenharmony_ci      .usage = usage,
564bf215546Sopenharmony_ci      .flags = createFlags,
565bf215546Sopenharmony_ci   };
566bf215546Sopenharmony_ci
567bf215546Sopenharmony_ci   return get_image_format_properties(physical_device, &info, tiling,
568bf215546Sopenharmony_ci                                      pImageFormatProperties, NULL);
569bf215546Sopenharmony_ci}
570bf215546Sopenharmony_ci
571bf215546Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL
572bf215546Sopenharmony_civ3dv_GetPhysicalDeviceImageFormatProperties2(VkPhysicalDevice physicalDevice,
573bf215546Sopenharmony_ci                                             const VkPhysicalDeviceImageFormatInfo2 *base_info,
574bf215546Sopenharmony_ci                                             VkImageFormatProperties2 *base_props)
575bf215546Sopenharmony_ci{
576bf215546Sopenharmony_ci   V3DV_FROM_HANDLE(v3dv_physical_device, physical_device, physicalDevice);
577bf215546Sopenharmony_ci   const VkPhysicalDeviceExternalImageFormatInfo *external_info = NULL;
578bf215546Sopenharmony_ci   const VkPhysicalDeviceImageDrmFormatModifierInfoEXT *drm_format_mod_info = NULL;
579bf215546Sopenharmony_ci   VkExternalImageFormatProperties *external_props = NULL;
580bf215546Sopenharmony_ci   VkImageTiling tiling = base_info->tiling;
581bf215546Sopenharmony_ci
582bf215546Sopenharmony_ci   /* Extract input structs */
583bf215546Sopenharmony_ci   vk_foreach_struct_const(s, base_info->pNext) {
584bf215546Sopenharmony_ci      switch (s->sType) {
585bf215546Sopenharmony_ci      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO:
586bf215546Sopenharmony_ci         external_info = (const void *) s;
587bf215546Sopenharmony_ci         break;
588bf215546Sopenharmony_ci      case VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO:
589bf215546Sopenharmony_ci         /* Do nothing, get_image_format_properties() below will handle it */;
590bf215546Sopenharmony_ci         break;
591bf215546Sopenharmony_ci      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT:
592bf215546Sopenharmony_ci         drm_format_mod_info = (const void *) s;
593bf215546Sopenharmony_ci         switch (drm_format_mod_info->drmFormatModifier) {
594bf215546Sopenharmony_ci         case DRM_FORMAT_MOD_LINEAR:
595bf215546Sopenharmony_ci            tiling = VK_IMAGE_TILING_LINEAR;
596bf215546Sopenharmony_ci            break;
597bf215546Sopenharmony_ci         case DRM_FORMAT_MOD_BROADCOM_UIF:
598bf215546Sopenharmony_ci            tiling = VK_IMAGE_TILING_OPTIMAL;
599bf215546Sopenharmony_ci            break;
600bf215546Sopenharmony_ci         default:
601bf215546Sopenharmony_ci            assert("Unknown DRM format modifier");
602bf215546Sopenharmony_ci         }
603bf215546Sopenharmony_ci         break;
604bf215546Sopenharmony_ci      default:
605bf215546Sopenharmony_ci         v3dv_debug_ignored_stype(s->sType);
606bf215546Sopenharmony_ci         break;
607bf215546Sopenharmony_ci      }
608bf215546Sopenharmony_ci   }
609bf215546Sopenharmony_ci
610bf215546Sopenharmony_ci   assert(tiling == VK_IMAGE_TILING_OPTIMAL ||
611bf215546Sopenharmony_ci          tiling == VK_IMAGE_TILING_LINEAR);
612bf215546Sopenharmony_ci
613bf215546Sopenharmony_ci   /* Extract output structs */
614bf215546Sopenharmony_ci   vk_foreach_struct(s, base_props->pNext) {
615bf215546Sopenharmony_ci      switch (s->sType) {
616bf215546Sopenharmony_ci      case VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES:
617bf215546Sopenharmony_ci         external_props = (void *) s;
618bf215546Sopenharmony_ci         break;
619bf215546Sopenharmony_ci      default:
620bf215546Sopenharmony_ci         v3dv_debug_ignored_stype(s->sType);
621bf215546Sopenharmony_ci         break;
622bf215546Sopenharmony_ci      }
623bf215546Sopenharmony_ci   }
624bf215546Sopenharmony_ci
625bf215546Sopenharmony_ci   VkResult result =
626bf215546Sopenharmony_ci      get_image_format_properties(physical_device, base_info, tiling,
627bf215546Sopenharmony_ci                                  &base_props->imageFormatProperties, NULL);
628bf215546Sopenharmony_ci   if (result != VK_SUCCESS)
629bf215546Sopenharmony_ci      goto done;
630bf215546Sopenharmony_ci
631bf215546Sopenharmony_ci   if (external_info && external_info->handleType != 0) {
632bf215546Sopenharmony_ci      switch (external_info->handleType) {
633bf215546Sopenharmony_ci      case VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT:
634bf215546Sopenharmony_ci      case VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT:
635bf215546Sopenharmony_ci         if (external_props)
636bf215546Sopenharmony_ci            external_props->externalMemoryProperties = prime_fd_props;
637bf215546Sopenharmony_ci         break;
638bf215546Sopenharmony_ci      default:
639bf215546Sopenharmony_ci         result = VK_ERROR_FORMAT_NOT_SUPPORTED;
640bf215546Sopenharmony_ci         break;
641bf215546Sopenharmony_ci      }
642bf215546Sopenharmony_ci   }
643bf215546Sopenharmony_ci
644bf215546Sopenharmony_cidone:
645bf215546Sopenharmony_ci   return result;
646bf215546Sopenharmony_ci}
647bf215546Sopenharmony_ci
648bf215546Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL
649bf215546Sopenharmony_civ3dv_GetPhysicalDeviceSparseImageFormatProperties(
650bf215546Sopenharmony_ci   VkPhysicalDevice physicalDevice,
651bf215546Sopenharmony_ci   VkFormat format,
652bf215546Sopenharmony_ci   VkImageType type,
653bf215546Sopenharmony_ci   VkSampleCountFlagBits samples,
654bf215546Sopenharmony_ci   VkImageUsageFlags usage,
655bf215546Sopenharmony_ci   VkImageTiling tiling,
656bf215546Sopenharmony_ci   uint32_t *pPropertyCount,
657bf215546Sopenharmony_ci   VkSparseImageFormatProperties *pProperties)
658bf215546Sopenharmony_ci{
659bf215546Sopenharmony_ci   *pPropertyCount = 0;
660bf215546Sopenharmony_ci}
661bf215546Sopenharmony_ci
662bf215546Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL
663bf215546Sopenharmony_civ3dv_GetPhysicalDeviceSparseImageFormatProperties2(
664bf215546Sopenharmony_ci   VkPhysicalDevice physicalDevice,
665bf215546Sopenharmony_ci   const VkPhysicalDeviceSparseImageFormatInfo2 *pFormatInfo,
666bf215546Sopenharmony_ci   uint32_t *pPropertyCount,
667bf215546Sopenharmony_ci   VkSparseImageFormatProperties2 *pProperties)
668bf215546Sopenharmony_ci{
669bf215546Sopenharmony_ci   *pPropertyCount = 0;
670bf215546Sopenharmony_ci}
671bf215546Sopenharmony_ci
672bf215546Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL
673bf215546Sopenharmony_civ3dv_GetPhysicalDeviceExternalBufferProperties(
674bf215546Sopenharmony_ci   VkPhysicalDevice physicalDevice,
675bf215546Sopenharmony_ci   const VkPhysicalDeviceExternalBufferInfo *pExternalBufferInfo,
676bf215546Sopenharmony_ci   VkExternalBufferProperties *pExternalBufferProperties)
677bf215546Sopenharmony_ci{
678bf215546Sopenharmony_ci   switch (pExternalBufferInfo->handleType) {
679bf215546Sopenharmony_ci   case VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT:
680bf215546Sopenharmony_ci   case VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT:
681bf215546Sopenharmony_ci      pExternalBufferProperties->externalMemoryProperties = prime_fd_props;
682bf215546Sopenharmony_ci      return;
683bf215546Sopenharmony_ci   default: /* Unsupported */
684bf215546Sopenharmony_ci      pExternalBufferProperties->externalMemoryProperties =
685bf215546Sopenharmony_ci         (VkExternalMemoryProperties) {
686bf215546Sopenharmony_ci            .compatibleHandleTypes = pExternalBufferInfo->handleType,
687bf215546Sopenharmony_ci         };
688bf215546Sopenharmony_ci      break;
689bf215546Sopenharmony_ci   }
690bf215546Sopenharmony_ci}
691