xref: /aosp_15_r20/external/mesa3d/src/freedreno/vulkan/tu_image.cc (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker  * Copyright © 2016 Red Hat.
3*61046927SAndroid Build Coastguard Worker  * Copyright © 2016 Bas Nieuwenhuizen
4*61046927SAndroid Build Coastguard Worker  * SPDX-License-Identifier: MIT
5*61046927SAndroid Build Coastguard Worker  *
6*61046927SAndroid Build Coastguard Worker  * based in part on anv driver which is:
7*61046927SAndroid Build Coastguard Worker  * Copyright © 2015 Intel Corporation
8*61046927SAndroid Build Coastguard Worker  */
9*61046927SAndroid Build Coastguard Worker 
10*61046927SAndroid Build Coastguard Worker #include "tu_image.h"
11*61046927SAndroid Build Coastguard Worker 
12*61046927SAndroid Build Coastguard Worker #include "fdl/fd6_format_table.h"
13*61046927SAndroid Build Coastguard Worker #include "common/freedreno_lrz.h"
14*61046927SAndroid Build Coastguard Worker 
15*61046927SAndroid Build Coastguard Worker #include "util/u_debug.h"
16*61046927SAndroid Build Coastguard Worker #include "util/format/u_format.h"
17*61046927SAndroid Build Coastguard Worker #include "vulkan/vulkan_android.h"
18*61046927SAndroid Build Coastguard Worker #include "vk_android.h"
19*61046927SAndroid Build Coastguard Worker #include "vk_debug_utils.h"
20*61046927SAndroid Build Coastguard Worker #include "vk_util.h"
21*61046927SAndroid Build Coastguard Worker #include "drm-uapi/drm_fourcc.h"
22*61046927SAndroid Build Coastguard Worker #include "vulkan/vulkan_core.h"
23*61046927SAndroid Build Coastguard Worker 
24*61046927SAndroid Build Coastguard Worker #include "tu_buffer.h"
25*61046927SAndroid Build Coastguard Worker #include "tu_cs.h"
26*61046927SAndroid Build Coastguard Worker #include "tu_descriptor_set.h"
27*61046927SAndroid Build Coastguard Worker #include "tu_device.h"
28*61046927SAndroid Build Coastguard Worker #include "tu_formats.h"
29*61046927SAndroid Build Coastguard Worker #include "tu_lrz.h"
30*61046927SAndroid Build Coastguard Worker #include "tu_rmv.h"
31*61046927SAndroid Build Coastguard Worker #include "tu_wsi.h"
32*61046927SAndroid Build Coastguard Worker 
33*61046927SAndroid Build Coastguard Worker uint32_t
tu6_plane_count(VkFormat format)34*61046927SAndroid Build Coastguard Worker tu6_plane_count(VkFormat format)
35*61046927SAndroid Build Coastguard Worker {
36*61046927SAndroid Build Coastguard Worker    switch (format) {
37*61046927SAndroid Build Coastguard Worker    case VK_FORMAT_D32_SFLOAT_S8_UINT:
38*61046927SAndroid Build Coastguard Worker       /* We do not support interleaved depth/stencil. Instead, we decompose to
39*61046927SAndroid Build Coastguard Worker        * a depth plane and a stencil plane.
40*61046927SAndroid Build Coastguard Worker        */
41*61046927SAndroid Build Coastguard Worker       return 2;
42*61046927SAndroid Build Coastguard Worker    default:
43*61046927SAndroid Build Coastguard Worker       return vk_format_get_plane_count(format);
44*61046927SAndroid Build Coastguard Worker    }
45*61046927SAndroid Build Coastguard Worker }
46*61046927SAndroid Build Coastguard Worker 
47*61046927SAndroid Build Coastguard Worker enum pipe_format
tu6_plane_format(VkFormat format,uint32_t plane)48*61046927SAndroid Build Coastguard Worker tu6_plane_format(VkFormat format, uint32_t plane)
49*61046927SAndroid Build Coastguard Worker {
50*61046927SAndroid Build Coastguard Worker    switch (format) {
51*61046927SAndroid Build Coastguard Worker    case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
52*61046927SAndroid Build Coastguard Worker       return plane ? PIPE_FORMAT_R8G8_UNORM : PIPE_FORMAT_Y8_UNORM;
53*61046927SAndroid Build Coastguard Worker    case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM:
54*61046927SAndroid Build Coastguard Worker       return PIPE_FORMAT_R8_UNORM;
55*61046927SAndroid Build Coastguard Worker    case VK_FORMAT_D32_SFLOAT_S8_UINT:
56*61046927SAndroid Build Coastguard Worker       return plane ? PIPE_FORMAT_S8_UINT : PIPE_FORMAT_Z32_FLOAT;
57*61046927SAndroid Build Coastguard Worker    default:
58*61046927SAndroid Build Coastguard Worker       return vk_format_to_pipe_format(format);
59*61046927SAndroid Build Coastguard Worker    }
60*61046927SAndroid Build Coastguard Worker }
61*61046927SAndroid Build Coastguard Worker 
62*61046927SAndroid Build Coastguard Worker uint32_t
tu6_plane_index(VkFormat format,VkImageAspectFlags aspect_mask)63*61046927SAndroid Build Coastguard Worker tu6_plane_index(VkFormat format, VkImageAspectFlags aspect_mask)
64*61046927SAndroid Build Coastguard Worker {
65*61046927SAndroid Build Coastguard Worker    switch (aspect_mask) {
66*61046927SAndroid Build Coastguard Worker    default:
67*61046927SAndroid Build Coastguard Worker       assert(aspect_mask != VK_IMAGE_ASPECT_MEMORY_PLANE_3_BIT_EXT);
68*61046927SAndroid Build Coastguard Worker       return 0;
69*61046927SAndroid Build Coastguard Worker    case VK_IMAGE_ASPECT_PLANE_1_BIT:
70*61046927SAndroid Build Coastguard Worker    case VK_IMAGE_ASPECT_MEMORY_PLANE_1_BIT_EXT:
71*61046927SAndroid Build Coastguard Worker       return 1;
72*61046927SAndroid Build Coastguard Worker    case VK_IMAGE_ASPECT_PLANE_2_BIT:
73*61046927SAndroid Build Coastguard Worker    case VK_IMAGE_ASPECT_MEMORY_PLANE_2_BIT_EXT:
74*61046927SAndroid Build Coastguard Worker       return 2;
75*61046927SAndroid Build Coastguard Worker    case VK_IMAGE_ASPECT_STENCIL_BIT:
76*61046927SAndroid Build Coastguard Worker       return format == VK_FORMAT_D32_SFLOAT_S8_UINT;
77*61046927SAndroid Build Coastguard Worker    }
78*61046927SAndroid Build Coastguard Worker }
79*61046927SAndroid Build Coastguard Worker 
80*61046927SAndroid Build Coastguard Worker enum pipe_format
tu_format_for_aspect(enum pipe_format format,VkImageAspectFlags aspect_mask)81*61046927SAndroid Build Coastguard Worker tu_format_for_aspect(enum pipe_format format, VkImageAspectFlags aspect_mask)
82*61046927SAndroid Build Coastguard Worker {
83*61046927SAndroid Build Coastguard Worker    switch (format) {
84*61046927SAndroid Build Coastguard Worker    case PIPE_FORMAT_Z24_UNORM_S8_UINT:
85*61046927SAndroid Build Coastguard Worker       /* VK_IMAGE_ASPECT_COLOR_BIT is used internally for blits (despite we
86*61046927SAndroid Build Coastguard Worker        * also incorrectly advertise VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT for
87*61046927SAndroid Build Coastguard Worker        * depth formats).  Return PIPE_FORMAT_Z24_UNORM_S8_UINT_AS_R8G8B8A8 in
88*61046927SAndroid Build Coastguard Worker        * this case.
89*61046927SAndroid Build Coastguard Worker        *
90*61046927SAndroid Build Coastguard Worker        * Otherwise, return the appropriate pipe format and let fdl6_view_init
91*61046927SAndroid Build Coastguard Worker        * take care of the rest.
92*61046927SAndroid Build Coastguard Worker        */
93*61046927SAndroid Build Coastguard Worker       if (aspect_mask & VK_IMAGE_ASPECT_COLOR_BIT)
94*61046927SAndroid Build Coastguard Worker          return PIPE_FORMAT_Z24_UNORM_S8_UINT_AS_R8G8B8A8;
95*61046927SAndroid Build Coastguard Worker       if (aspect_mask & VK_IMAGE_ASPECT_STENCIL_BIT) {
96*61046927SAndroid Build Coastguard Worker          if (aspect_mask & VK_IMAGE_ASPECT_DEPTH_BIT)
97*61046927SAndroid Build Coastguard Worker             return PIPE_FORMAT_Z24_UNORM_S8_UINT;
98*61046927SAndroid Build Coastguard Worker          else
99*61046927SAndroid Build Coastguard Worker             return PIPE_FORMAT_X24S8_UINT;
100*61046927SAndroid Build Coastguard Worker       } else {
101*61046927SAndroid Build Coastguard Worker          return PIPE_FORMAT_Z24X8_UNORM;
102*61046927SAndroid Build Coastguard Worker       }
103*61046927SAndroid Build Coastguard Worker    case PIPE_FORMAT_Z24X8_UNORM:
104*61046927SAndroid Build Coastguard Worker       if (aspect_mask & VK_IMAGE_ASPECT_COLOR_BIT)
105*61046927SAndroid Build Coastguard Worker          return PIPE_FORMAT_Z24_UNORM_S8_UINT_AS_R8G8B8A8;
106*61046927SAndroid Build Coastguard Worker       return PIPE_FORMAT_Z24X8_UNORM;
107*61046927SAndroid Build Coastguard Worker    default:
108*61046927SAndroid Build Coastguard Worker       return format;
109*61046927SAndroid Build Coastguard Worker    }
110*61046927SAndroid Build Coastguard Worker }
111*61046927SAndroid Build Coastguard Worker 
112*61046927SAndroid Build Coastguard Worker static bool
tu_is_r8g8(enum pipe_format format)113*61046927SAndroid Build Coastguard Worker tu_is_r8g8(enum pipe_format format)
114*61046927SAndroid Build Coastguard Worker {
115*61046927SAndroid Build Coastguard Worker    return (util_format_get_blocksize(format) == 2) &&
116*61046927SAndroid Build Coastguard Worker           (util_format_get_nr_components(format) == 2);
117*61046927SAndroid Build Coastguard Worker }
118*61046927SAndroid Build Coastguard Worker 
119*61046927SAndroid Build Coastguard Worker static bool
tu_is_r8g8_compatible(enum pipe_format format)120*61046927SAndroid Build Coastguard Worker tu_is_r8g8_compatible(enum pipe_format format)
121*61046927SAndroid Build Coastguard Worker {
122*61046927SAndroid Build Coastguard Worker    return (util_format_get_blocksize(format) == 2) &&
123*61046927SAndroid Build Coastguard Worker           !util_format_is_depth_or_stencil(format);
124*61046927SAndroid Build Coastguard Worker }
125*61046927SAndroid Build Coastguard Worker 
126*61046927SAndroid Build Coastguard Worker uint64_t
tu_layer_address(const struct fdl6_view * iview,uint32_t layer)127*61046927SAndroid Build Coastguard Worker tu_layer_address(const struct fdl6_view *iview, uint32_t layer)
128*61046927SAndroid Build Coastguard Worker {
129*61046927SAndroid Build Coastguard Worker    return iview->base_addr + iview->layer_size * layer;
130*61046927SAndroid Build Coastguard Worker }
131*61046927SAndroid Build Coastguard Worker 
132*61046927SAndroid Build Coastguard Worker void
tu_cs_image_ref(struct tu_cs * cs,const struct fdl6_view * iview,uint32_t layer)133*61046927SAndroid Build Coastguard Worker tu_cs_image_ref(struct tu_cs *cs, const struct fdl6_view *iview, uint32_t layer)
134*61046927SAndroid Build Coastguard Worker {
135*61046927SAndroid Build Coastguard Worker    tu_cs_emit(cs, A6XX_RB_MRT_PITCH(0, iview->pitch).value);
136*61046927SAndroid Build Coastguard Worker    tu_cs_emit(cs, iview->layer_size >> 6);
137*61046927SAndroid Build Coastguard Worker    tu_cs_emit_qw(cs, tu_layer_address(iview, layer));
138*61046927SAndroid Build Coastguard Worker }
139*61046927SAndroid Build Coastguard Worker 
140*61046927SAndroid Build Coastguard Worker void
tu_cs_image_stencil_ref(struct tu_cs * cs,const struct tu_image_view * iview,uint32_t layer)141*61046927SAndroid Build Coastguard Worker tu_cs_image_stencil_ref(struct tu_cs *cs, const struct tu_image_view *iview, uint32_t layer)
142*61046927SAndroid Build Coastguard Worker {
143*61046927SAndroid Build Coastguard Worker    tu_cs_emit(cs, A6XX_RB_STENCIL_BUFFER_PITCH(iview->stencil_pitch).value);
144*61046927SAndroid Build Coastguard Worker    tu_cs_emit(cs, iview->stencil_layer_size >> 6);
145*61046927SAndroid Build Coastguard Worker    tu_cs_emit_qw(cs, iview->stencil_base_addr + iview->stencil_layer_size * layer);
146*61046927SAndroid Build Coastguard Worker }
147*61046927SAndroid Build Coastguard Worker 
148*61046927SAndroid Build Coastguard Worker void
tu_cs_image_depth_ref(struct tu_cs * cs,const struct tu_image_view * iview,uint32_t layer)149*61046927SAndroid Build Coastguard Worker tu_cs_image_depth_ref(struct tu_cs *cs, const struct tu_image_view *iview, uint32_t layer)
150*61046927SAndroid Build Coastguard Worker {
151*61046927SAndroid Build Coastguard Worker    tu_cs_emit(cs, A6XX_RB_DEPTH_BUFFER_PITCH(iview->depth_pitch).value);
152*61046927SAndroid Build Coastguard Worker    tu_cs_emit(cs, iview->depth_layer_size >> 6);
153*61046927SAndroid Build Coastguard Worker    tu_cs_emit_qw(cs, iview->depth_base_addr + iview->depth_layer_size * layer);
154*61046927SAndroid Build Coastguard Worker }
155*61046927SAndroid Build Coastguard Worker 
156*61046927SAndroid Build Coastguard Worker template <chip CHIP>
157*61046927SAndroid Build Coastguard Worker void
tu_cs_image_ref_2d(struct tu_cs * cs,const struct fdl6_view * iview,uint32_t layer,bool src)158*61046927SAndroid Build Coastguard Worker tu_cs_image_ref_2d(struct tu_cs *cs, const struct fdl6_view *iview, uint32_t layer, bool src)
159*61046927SAndroid Build Coastguard Worker {
160*61046927SAndroid Build Coastguard Worker    tu_cs_emit_qw(cs, iview->base_addr + iview->layer_size * layer);
161*61046927SAndroid Build Coastguard Worker    /* SP_PS_2D_SRC_PITCH has shifted pitch field */
162*61046927SAndroid Build Coastguard Worker    if (src)
163*61046927SAndroid Build Coastguard Worker       tu_cs_emit(cs, SP_PS_2D_SRC_PITCH(CHIP, .pitch = iview->pitch).value);
164*61046927SAndroid Build Coastguard Worker    else
165*61046927SAndroid Build Coastguard Worker       tu_cs_emit(cs, A6XX_RB_2D_DST_PITCH(iview->pitch).value);
166*61046927SAndroid Build Coastguard Worker }
167*61046927SAndroid Build Coastguard Worker TU_GENX(tu_cs_image_ref_2d);
168*61046927SAndroid Build Coastguard Worker 
169*61046927SAndroid Build Coastguard Worker void
tu_cs_image_flag_ref(struct tu_cs * cs,const struct fdl6_view * iview,uint32_t layer)170*61046927SAndroid Build Coastguard Worker tu_cs_image_flag_ref(struct tu_cs *cs, const struct fdl6_view *iview, uint32_t layer)
171*61046927SAndroid Build Coastguard Worker {
172*61046927SAndroid Build Coastguard Worker    tu_cs_emit_qw(cs, iview->ubwc_addr + iview->ubwc_layer_size * layer);
173*61046927SAndroid Build Coastguard Worker    tu_cs_emit(cs, iview->FLAG_BUFFER_PITCH);
174*61046927SAndroid Build Coastguard Worker }
175*61046927SAndroid Build Coastguard Worker 
176*61046927SAndroid Build Coastguard Worker static void
tu_image_view_init(struct tu_device * device,struct tu_image_view * iview,const VkImageViewCreateInfo * pCreateInfo,bool has_z24uint_s8uint)177*61046927SAndroid Build Coastguard Worker tu_image_view_init(struct tu_device *device,
178*61046927SAndroid Build Coastguard Worker                    struct tu_image_view *iview,
179*61046927SAndroid Build Coastguard Worker                    const VkImageViewCreateInfo *pCreateInfo,
180*61046927SAndroid Build Coastguard Worker                    bool has_z24uint_s8uint)
181*61046927SAndroid Build Coastguard Worker {
182*61046927SAndroid Build Coastguard Worker    VK_FROM_HANDLE(tu_image, image, pCreateInfo->image);
183*61046927SAndroid Build Coastguard Worker    const VkImageSubresourceRange *range = &pCreateInfo->subresourceRange;
184*61046927SAndroid Build Coastguard Worker    VkFormat vk_format =
185*61046927SAndroid Build Coastguard Worker       vk_select_android_external_format(pCreateInfo->pNext, pCreateInfo->format);
186*61046927SAndroid Build Coastguard Worker 
187*61046927SAndroid Build Coastguard Worker    /* With AHB, the app may be using an external format but not necessarily
188*61046927SAndroid Build Coastguard Worker     * chain the VkExternalFormatANDROID.  In this case, just take the format
189*61046927SAndroid Build Coastguard Worker     * from the image.
190*61046927SAndroid Build Coastguard Worker     */
191*61046927SAndroid Build Coastguard Worker    if ((vk_format == VK_FORMAT_UNDEFINED) &&
192*61046927SAndroid Build Coastguard Worker        (image->vk.external_handle_types & VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID))
193*61046927SAndroid Build Coastguard Worker        vk_format = image->vk.format;
194*61046927SAndroid Build Coastguard Worker 
195*61046927SAndroid Build Coastguard Worker    VkImageAspectFlags aspect_mask = pCreateInfo->subresourceRange.aspectMask;
196*61046927SAndroid Build Coastguard Worker 
197*61046927SAndroid Build Coastguard Worker    const struct VkSamplerYcbcrConversionInfo *ycbcr_conversion =
198*61046927SAndroid Build Coastguard Worker       vk_find_struct_const(pCreateInfo->pNext, SAMPLER_YCBCR_CONVERSION_INFO);
199*61046927SAndroid Build Coastguard Worker    const struct vk_ycbcr_conversion *conversion = ycbcr_conversion ?
200*61046927SAndroid Build Coastguard Worker       vk_ycbcr_conversion_from_handle(ycbcr_conversion->conversion) : NULL;
201*61046927SAndroid Build Coastguard Worker 
202*61046927SAndroid Build Coastguard Worker    vk_image_view_init(&device->vk, &iview->vk, false, pCreateInfo);
203*61046927SAndroid Build Coastguard Worker 
204*61046927SAndroid Build Coastguard Worker    iview->image = image;
205*61046927SAndroid Build Coastguard Worker 
206*61046927SAndroid Build Coastguard Worker    const struct fdl_layout *layouts[3];
207*61046927SAndroid Build Coastguard Worker 
208*61046927SAndroid Build Coastguard Worker    layouts[0] = &image->layout[tu6_plane_index(image->vk.format, aspect_mask)];
209*61046927SAndroid Build Coastguard Worker 
210*61046927SAndroid Build Coastguard Worker    enum pipe_format format;
211*61046927SAndroid Build Coastguard Worker    if (aspect_mask != VK_IMAGE_ASPECT_COLOR_BIT)
212*61046927SAndroid Build Coastguard Worker       format = tu6_plane_format(vk_format, tu6_plane_index(vk_format, aspect_mask));
213*61046927SAndroid Build Coastguard Worker    else
214*61046927SAndroid Build Coastguard Worker       format = vk_format_to_pipe_format(vk_format);
215*61046927SAndroid Build Coastguard Worker 
216*61046927SAndroid Build Coastguard Worker    if (image->vk.format == VK_FORMAT_G8_B8R8_2PLANE_420_UNORM &&
217*61046927SAndroid Build Coastguard Worker        aspect_mask == VK_IMAGE_ASPECT_PLANE_0_BIT) {
218*61046927SAndroid Build Coastguard Worker       if (vk_format == VK_FORMAT_R8_UNORM) {
219*61046927SAndroid Build Coastguard Worker          /* The 0'th plane of this format has a different UBWC compression. */
220*61046927SAndroid Build Coastguard Worker          format = PIPE_FORMAT_Y8_UNORM;
221*61046927SAndroid Build Coastguard Worker       } else {
222*61046927SAndroid Build Coastguard Worker          /* If the user wants to reinterpret this plane, then they should've
223*61046927SAndroid Build Coastguard Worker           * set MUTABLE_FORMAT_BIT which should disable UBWC and tiling.
224*61046927SAndroid Build Coastguard Worker           */
225*61046927SAndroid Build Coastguard Worker          assert(!layouts[0]->ubwc);
226*61046927SAndroid Build Coastguard Worker       }
227*61046927SAndroid Build Coastguard Worker    }
228*61046927SAndroid Build Coastguard Worker 
229*61046927SAndroid Build Coastguard Worker    if (aspect_mask == VK_IMAGE_ASPECT_COLOR_BIT &&
230*61046927SAndroid Build Coastguard Worker        (vk_format == VK_FORMAT_G8_B8R8_2PLANE_420_UNORM ||
231*61046927SAndroid Build Coastguard Worker         vk_format == VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM)) {
232*61046927SAndroid Build Coastguard Worker       layouts[1] = &image->layout[1];
233*61046927SAndroid Build Coastguard Worker       layouts[2] = &image->layout[2];
234*61046927SAndroid Build Coastguard Worker    }
235*61046927SAndroid Build Coastguard Worker 
236*61046927SAndroid Build Coastguard Worker    vk_component_mapping_to_pipe_swizzle(pCreateInfo->components,
237*61046927SAndroid Build Coastguard Worker                                         iview->swizzle);
238*61046927SAndroid Build Coastguard Worker 
239*61046927SAndroid Build Coastguard Worker    struct fdl_view_args args = {};
240*61046927SAndroid Build Coastguard Worker    args.chip = device->physical_device->info->chip;
241*61046927SAndroid Build Coastguard Worker    args.iova = image->iova;
242*61046927SAndroid Build Coastguard Worker    args.base_array_layer = range->baseArrayLayer;
243*61046927SAndroid Build Coastguard Worker    args.base_miplevel = range->baseMipLevel;
244*61046927SAndroid Build Coastguard Worker    args.layer_count = vk_image_subresource_layer_count(&image->vk, range);
245*61046927SAndroid Build Coastguard Worker    args.level_count = vk_image_subresource_level_count(&image->vk, range);
246*61046927SAndroid Build Coastguard Worker    args.min_lod_clamp = iview->vk.min_lod;
247*61046927SAndroid Build Coastguard Worker    args.format = tu_format_for_aspect(format, aspect_mask);
248*61046927SAndroid Build Coastguard Worker    args.ubwc_fc_mutable = image->ubwc_fc_mutable;
249*61046927SAndroid Build Coastguard Worker    vk_component_mapping_to_pipe_swizzle(pCreateInfo->components, args.swiz);
250*61046927SAndroid Build Coastguard Worker    if (conversion) {
251*61046927SAndroid Build Coastguard Worker       unsigned char conversion_swiz[4], create_swiz[4];
252*61046927SAndroid Build Coastguard Worker       memcpy(create_swiz, args.swiz, sizeof(create_swiz));
253*61046927SAndroid Build Coastguard Worker 
254*61046927SAndroid Build Coastguard Worker       VkComponentMapping component = {
255*61046927SAndroid Build Coastguard Worker          .r = conversion->state.mapping[0],
256*61046927SAndroid Build Coastguard Worker          .g = conversion->state.mapping[1],
257*61046927SAndroid Build Coastguard Worker          .b = conversion->state.mapping[2],
258*61046927SAndroid Build Coastguard Worker          .a = conversion->state.mapping[3]
259*61046927SAndroid Build Coastguard Worker       };
260*61046927SAndroid Build Coastguard Worker       vk_component_mapping_to_pipe_swizzle(component, conversion_swiz);
261*61046927SAndroid Build Coastguard Worker       util_format_compose_swizzles(create_swiz, conversion_swiz, args.swiz);
262*61046927SAndroid Build Coastguard Worker    }
263*61046927SAndroid Build Coastguard Worker 
264*61046927SAndroid Build Coastguard Worker    switch (pCreateInfo->viewType) {
265*61046927SAndroid Build Coastguard Worker    case VK_IMAGE_VIEW_TYPE_1D:
266*61046927SAndroid Build Coastguard Worker    case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
267*61046927SAndroid Build Coastguard Worker       args.type = FDL_VIEW_TYPE_1D;
268*61046927SAndroid Build Coastguard Worker       break;
269*61046927SAndroid Build Coastguard Worker    case VK_IMAGE_VIEW_TYPE_2D:
270*61046927SAndroid Build Coastguard Worker    case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
271*61046927SAndroid Build Coastguard Worker       args.type = FDL_VIEW_TYPE_2D;
272*61046927SAndroid Build Coastguard Worker       break;
273*61046927SAndroid Build Coastguard Worker    case VK_IMAGE_VIEW_TYPE_CUBE:
274*61046927SAndroid Build Coastguard Worker    case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
275*61046927SAndroid Build Coastguard Worker       args.type = FDL_VIEW_TYPE_CUBE;
276*61046927SAndroid Build Coastguard Worker       break;
277*61046927SAndroid Build Coastguard Worker    case VK_IMAGE_VIEW_TYPE_3D:
278*61046927SAndroid Build Coastguard Worker       args.type = FDL_VIEW_TYPE_3D;
279*61046927SAndroid Build Coastguard Worker       break;
280*61046927SAndroid Build Coastguard Worker    default:
281*61046927SAndroid Build Coastguard Worker       unreachable("unknown view type");
282*61046927SAndroid Build Coastguard Worker    }
283*61046927SAndroid Build Coastguard Worker 
284*61046927SAndroid Build Coastguard Worker    STATIC_ASSERT((unsigned)VK_CHROMA_LOCATION_COSITED_EVEN == (unsigned)FDL_CHROMA_LOCATION_COSITED_EVEN);
285*61046927SAndroid Build Coastguard Worker    STATIC_ASSERT((unsigned)VK_CHROMA_LOCATION_MIDPOINT == (unsigned)FDL_CHROMA_LOCATION_MIDPOINT);
286*61046927SAndroid Build Coastguard Worker    if (conversion) {
287*61046927SAndroid Build Coastguard Worker       args.chroma_offsets[0] = (enum fdl_chroma_location) conversion->state.chroma_offsets[0];
288*61046927SAndroid Build Coastguard Worker       args.chroma_offsets[1] = (enum fdl_chroma_location) conversion->state.chroma_offsets[1];
289*61046927SAndroid Build Coastguard Worker    }
290*61046927SAndroid Build Coastguard Worker 
291*61046927SAndroid Build Coastguard Worker    fdl6_view_init(&iview->view, layouts, &args, has_z24uint_s8uint);
292*61046927SAndroid Build Coastguard Worker 
293*61046927SAndroid Build Coastguard Worker    if (image->vk.format == VK_FORMAT_D32_SFLOAT_S8_UINT) {
294*61046927SAndroid Build Coastguard Worker       struct fdl_layout *layout = &image->layout[0];
295*61046927SAndroid Build Coastguard Worker       iview->depth_base_addr = image->iova +
296*61046927SAndroid Build Coastguard Worker          fdl_surface_offset(layout, range->baseMipLevel, range->baseArrayLayer);
297*61046927SAndroid Build Coastguard Worker       iview->depth_layer_size = fdl_layer_stride(layout, range->baseMipLevel);
298*61046927SAndroid Build Coastguard Worker       iview->depth_pitch = fdl_pitch(layout, range->baseMipLevel);
299*61046927SAndroid Build Coastguard Worker 
300*61046927SAndroid Build Coastguard Worker       layout = &image->layout[1];
301*61046927SAndroid Build Coastguard Worker       iview->stencil_base_addr = image->iova +
302*61046927SAndroid Build Coastguard Worker          fdl_surface_offset(layout, range->baseMipLevel, range->baseArrayLayer);
303*61046927SAndroid Build Coastguard Worker       iview->stencil_layer_size = fdl_layer_stride(layout, range->baseMipLevel);
304*61046927SAndroid Build Coastguard Worker       iview->stencil_pitch = fdl_pitch(layout, range->baseMipLevel);
305*61046927SAndroid Build Coastguard Worker    }
306*61046927SAndroid Build Coastguard Worker }
307*61046927SAndroid Build Coastguard Worker 
308*61046927SAndroid Build Coastguard Worker bool
tiling_possible(VkFormat format)309*61046927SAndroid Build Coastguard Worker tiling_possible(VkFormat format)
310*61046927SAndroid Build Coastguard Worker {
311*61046927SAndroid Build Coastguard Worker    if (format == VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM ||
312*61046927SAndroid Build Coastguard Worker        format == VK_FORMAT_G8B8G8R8_422_UNORM ||
313*61046927SAndroid Build Coastguard Worker        format == VK_FORMAT_B8G8R8G8_422_UNORM)
314*61046927SAndroid Build Coastguard Worker       return false;
315*61046927SAndroid Build Coastguard Worker 
316*61046927SAndroid Build Coastguard Worker    return true;
317*61046927SAndroid Build Coastguard Worker }
318*61046927SAndroid Build Coastguard Worker 
319*61046927SAndroid Build Coastguard Worker /* Checks if we should advertise UBWC support for the given usage.
320*61046927SAndroid Build Coastguard Worker  *
321*61046927SAndroid Build Coastguard Worker  * Used by both vkCreateImage and vkGetPhysicalDeviceFormatProperties2, so the
322*61046927SAndroid Build Coastguard Worker  * logical tu_device may be NULL.
323*61046927SAndroid Build Coastguard Worker  */
324*61046927SAndroid Build Coastguard Worker bool
ubwc_possible(struct tu_device * device,VkFormat format,VkImageType type,VkImageUsageFlags usage,VkImageUsageFlags stencil_usage,const struct fd_dev_info * info,VkSampleCountFlagBits samples,bool use_z24uint_s8uint)325*61046927SAndroid Build Coastguard Worker ubwc_possible(struct tu_device *device,
326*61046927SAndroid Build Coastguard Worker               VkFormat format,
327*61046927SAndroid Build Coastguard Worker               VkImageType type,
328*61046927SAndroid Build Coastguard Worker               VkImageUsageFlags usage,
329*61046927SAndroid Build Coastguard Worker               VkImageUsageFlags stencil_usage,
330*61046927SAndroid Build Coastguard Worker               const struct fd_dev_info *info,
331*61046927SAndroid Build Coastguard Worker               VkSampleCountFlagBits samples,
332*61046927SAndroid Build Coastguard Worker               bool use_z24uint_s8uint)
333*61046927SAndroid Build Coastguard Worker {
334*61046927SAndroid Build Coastguard Worker    /* no UBWC with compressed formats, E5B9G9R9, S8_UINT
335*61046927SAndroid Build Coastguard Worker     * (S8_UINT because separate stencil doesn't have UBWC-enable bit)
336*61046927SAndroid Build Coastguard Worker     */
337*61046927SAndroid Build Coastguard Worker    if (vk_format_is_compressed(format) ||
338*61046927SAndroid Build Coastguard Worker        format == VK_FORMAT_E5B9G9R9_UFLOAT_PACK32 ||
339*61046927SAndroid Build Coastguard Worker        format == VK_FORMAT_S8_UINT)
340*61046927SAndroid Build Coastguard Worker       return false;
341*61046927SAndroid Build Coastguard Worker 
342*61046927SAndroid Build Coastguard Worker    /* In copy_format, we treat snorm as unorm to avoid clamping.  But snorm
343*61046927SAndroid Build Coastguard Worker     * and unorm are UBWC incompatible for special values such as all 0's or
344*61046927SAndroid Build Coastguard Worker     * all 1's prior to a740.  Disable UBWC for snorm.
345*61046927SAndroid Build Coastguard Worker     */
346*61046927SAndroid Build Coastguard Worker    if (vk_format_is_snorm(format) &&
347*61046927SAndroid Build Coastguard Worker        !info->a7xx.ubwc_unorm_snorm_int_compatible)
348*61046927SAndroid Build Coastguard Worker       return false;
349*61046927SAndroid Build Coastguard Worker 
350*61046927SAndroid Build Coastguard Worker    if (!info->a6xx.has_8bpp_ubwc &&
351*61046927SAndroid Build Coastguard Worker        vk_format_get_blocksizebits(format) == 8 &&
352*61046927SAndroid Build Coastguard Worker        vk_format_get_plane_count(format) == 1)
353*61046927SAndroid Build Coastguard Worker       return false;
354*61046927SAndroid Build Coastguard Worker 
355*61046927SAndroid Build Coastguard Worker    if (type == VK_IMAGE_TYPE_3D) {
356*61046927SAndroid Build Coastguard Worker       if (device) {
357*61046927SAndroid Build Coastguard Worker          perf_debug(device,
358*61046927SAndroid Build Coastguard Worker                     "Disabling UBWC for %s 3D image, but it should be "
359*61046927SAndroid Build Coastguard Worker                     "possible to support.",
360*61046927SAndroid Build Coastguard Worker                     util_format_name(vk_format_to_pipe_format(format)));
361*61046927SAndroid Build Coastguard Worker       }
362*61046927SAndroid Build Coastguard Worker       return false;
363*61046927SAndroid Build Coastguard Worker    }
364*61046927SAndroid Build Coastguard Worker 
365*61046927SAndroid Build Coastguard Worker    /* Disable UBWC for storage images when not supported.
366*61046927SAndroid Build Coastguard Worker     *
367*61046927SAndroid Build Coastguard Worker     * Prior to a7xx, storage images must be readonly or writeonly to use UBWC.
368*61046927SAndroid Build Coastguard Worker     * Freedreno can determine when this isn't the case and decompress the
369*61046927SAndroid Build Coastguard Worker     * image on-the-fly, but we don't know which image a binding corresponds to
370*61046927SAndroid Build Coastguard Worker     * and we can't change the descriptor so we can't do this.
371*61046927SAndroid Build Coastguard Worker     */
372*61046927SAndroid Build Coastguard Worker    if (((usage | stencil_usage) & VK_IMAGE_USAGE_STORAGE_BIT) &&
373*61046927SAndroid Build Coastguard Worker        !info->a7xx.supports_ibo_ubwc) {
374*61046927SAndroid Build Coastguard Worker       return false;
375*61046927SAndroid Build Coastguard Worker    }
376*61046927SAndroid Build Coastguard Worker 
377*61046927SAndroid Build Coastguard Worker    /* A690 seem to have broken UBWC for depth/stencil, it requires
378*61046927SAndroid Build Coastguard Worker     * depth flushing where we cannot realistically place it, like between
379*61046927SAndroid Build Coastguard Worker     * ordinary draw calls writing read/depth. WSL blob seem to use ubwc
380*61046927SAndroid Build Coastguard Worker     * sometimes for depth/stencil.
381*61046927SAndroid Build Coastguard Worker     */
382*61046927SAndroid Build Coastguard Worker    if (info->a6xx.broken_ds_ubwc_quirk &&
383*61046927SAndroid Build Coastguard Worker        vk_format_is_depth_or_stencil(format))
384*61046927SAndroid Build Coastguard Worker       return false;
385*61046927SAndroid Build Coastguard Worker 
386*61046927SAndroid Build Coastguard Worker    /* Disable UBWC for D24S8 on A630 in some cases
387*61046927SAndroid Build Coastguard Worker     *
388*61046927SAndroid Build Coastguard Worker     * VK_IMAGE_ASPECT_STENCIL_BIT image view requires to be able to sample
389*61046927SAndroid Build Coastguard Worker     * from the stencil component as UINT, however no format allows this
390*61046927SAndroid Build Coastguard Worker     * on a630 (the special FMT6_Z24_UINT_S8_UINT format is missing)
391*61046927SAndroid Build Coastguard Worker     *
392*61046927SAndroid Build Coastguard Worker     * It must be sampled as FMT6_8_8_8_8_UINT, which is not UBWC-compatible
393*61046927SAndroid Build Coastguard Worker     *
394*61046927SAndroid Build Coastguard Worker     * If we wish to get the border colors correct without knowing the format
395*61046927SAndroid Build Coastguard Worker     * when creating the sampler, we also have to use the A630 workaround.
396*61046927SAndroid Build Coastguard Worker     */
397*61046927SAndroid Build Coastguard Worker    if (!use_z24uint_s8uint &&
398*61046927SAndroid Build Coastguard Worker        format == VK_FORMAT_D24_UNORM_S8_UINT &&
399*61046927SAndroid Build Coastguard Worker        (stencil_usage & (VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)))
400*61046927SAndroid Build Coastguard Worker       return false;
401*61046927SAndroid Build Coastguard Worker 
402*61046927SAndroid Build Coastguard Worker    if (!info->a6xx.has_z24uint_s8uint &&
403*61046927SAndroid Build Coastguard Worker        (format == VK_FORMAT_D24_UNORM_S8_UINT ||
404*61046927SAndroid Build Coastguard Worker         format == VK_FORMAT_X8_D24_UNORM_PACK32) &&
405*61046927SAndroid Build Coastguard Worker        samples > VK_SAMPLE_COUNT_1_BIT) {
406*61046927SAndroid Build Coastguard Worker       return false;
407*61046927SAndroid Build Coastguard Worker    }
408*61046927SAndroid Build Coastguard Worker 
409*61046927SAndroid Build Coastguard Worker    return true;
410*61046927SAndroid Build Coastguard Worker }
411*61046927SAndroid Build Coastguard Worker 
412*61046927SAndroid Build Coastguard Worker /* R8G8 have a different block width/height and height alignment from other
413*61046927SAndroid Build Coastguard Worker  * formats that would normally be compatible (like R16), and so if we are
414*61046927SAndroid Build Coastguard Worker  * trying to, for example, sample R16 as R8G8 we need to demote to linear.
415*61046927SAndroid Build Coastguard Worker  */
416*61046927SAndroid Build Coastguard Worker static bool
format_list_reinterprets_r8g8_r16(enum pipe_format format,const VkImageFormatListCreateInfo * fmt_list)417*61046927SAndroid Build Coastguard Worker format_list_reinterprets_r8g8_r16(enum pipe_format format, const VkImageFormatListCreateInfo *fmt_list)
418*61046927SAndroid Build Coastguard Worker {
419*61046927SAndroid Build Coastguard Worker    /* Check if it's actually a 2-cpp color format. */
420*61046927SAndroid Build Coastguard Worker    if (!tu_is_r8g8_compatible(format))
421*61046927SAndroid Build Coastguard Worker       return false;
422*61046927SAndroid Build Coastguard Worker 
423*61046927SAndroid Build Coastguard Worker    /* If there's no format list, then the app may reinterpret to any compatible
424*61046927SAndroid Build Coastguard Worker     * format.
425*61046927SAndroid Build Coastguard Worker     */
426*61046927SAndroid Build Coastguard Worker    if (!fmt_list || !fmt_list->viewFormatCount)
427*61046927SAndroid Build Coastguard Worker       return true;
428*61046927SAndroid Build Coastguard Worker 
429*61046927SAndroid Build Coastguard Worker    bool has_r8g8 = false;
430*61046927SAndroid Build Coastguard Worker    bool has_non_r8g8 = false;
431*61046927SAndroid Build Coastguard Worker    for (uint32_t i = 0; i < fmt_list->viewFormatCount; i++) {
432*61046927SAndroid Build Coastguard Worker       enum pipe_format format =
433*61046927SAndroid Build Coastguard Worker          vk_format_to_pipe_format(fmt_list->pViewFormats[i]);
434*61046927SAndroid Build Coastguard Worker       if (tu_is_r8g8(format))
435*61046927SAndroid Build Coastguard Worker          has_r8g8 = true;
436*61046927SAndroid Build Coastguard Worker       else
437*61046927SAndroid Build Coastguard Worker          has_non_r8g8 = true;
438*61046927SAndroid Build Coastguard Worker    }
439*61046927SAndroid Build Coastguard Worker    return has_r8g8 && has_non_r8g8;
440*61046927SAndroid Build Coastguard Worker }
441*61046927SAndroid Build Coastguard Worker 
442*61046927SAndroid Build Coastguard Worker static bool
format_list_has_swaps(const VkImageFormatListCreateInfo * fmt_list)443*61046927SAndroid Build Coastguard Worker format_list_has_swaps(const VkImageFormatListCreateInfo *fmt_list)
444*61046927SAndroid Build Coastguard Worker {
445*61046927SAndroid Build Coastguard Worker    /* If there's no format list, then the app may reinterpret to any compatible
446*61046927SAndroid Build Coastguard Worker     * format, and presumably one would have the swap set.
447*61046927SAndroid Build Coastguard Worker     */
448*61046927SAndroid Build Coastguard Worker    if (!fmt_list || !fmt_list->viewFormatCount)
449*61046927SAndroid Build Coastguard Worker       return true;
450*61046927SAndroid Build Coastguard Worker 
451*61046927SAndroid Build Coastguard Worker    for (uint32_t i = 0; i < fmt_list->viewFormatCount; i++) {
452*61046927SAndroid Build Coastguard Worker       enum pipe_format format =
453*61046927SAndroid Build Coastguard Worker          vk_format_to_pipe_format(fmt_list->pViewFormats[i]);
454*61046927SAndroid Build Coastguard Worker 
455*61046927SAndroid Build Coastguard Worker       if (tu6_format_texture(format, TILE6_LINEAR).swap)
456*61046927SAndroid Build Coastguard Worker          return true;
457*61046927SAndroid Build Coastguard Worker    }
458*61046927SAndroid Build Coastguard Worker    return false;
459*61046927SAndroid Build Coastguard Worker }
460*61046927SAndroid Build Coastguard Worker 
461*61046927SAndroid Build Coastguard Worker template <chip CHIP>
462*61046927SAndroid Build Coastguard Worker VkResult
tu_image_update_layout(struct tu_device * device,struct tu_image * image,uint64_t modifier,const VkSubresourceLayout * plane_layouts)463*61046927SAndroid Build Coastguard Worker tu_image_update_layout(struct tu_device *device, struct tu_image *image,
464*61046927SAndroid Build Coastguard Worker                        uint64_t modifier, const VkSubresourceLayout *plane_layouts)
465*61046927SAndroid Build Coastguard Worker {
466*61046927SAndroid Build Coastguard Worker    enum a6xx_tile_mode tile_mode = TILE6_3;
467*61046927SAndroid Build Coastguard Worker    image->vk.drm_format_mod = modifier;
468*61046927SAndroid Build Coastguard Worker 
469*61046927SAndroid Build Coastguard Worker    if (modifier == DRM_FORMAT_MOD_LINEAR) {
470*61046927SAndroid Build Coastguard Worker       image->force_linear_tile = true;
471*61046927SAndroid Build Coastguard Worker    }
472*61046927SAndroid Build Coastguard Worker 
473*61046927SAndroid Build Coastguard Worker    if (image->force_linear_tile) {
474*61046927SAndroid Build Coastguard Worker       tile_mode = TILE6_LINEAR;
475*61046927SAndroid Build Coastguard Worker       image->ubwc_enabled = false;
476*61046927SAndroid Build Coastguard Worker    }
477*61046927SAndroid Build Coastguard Worker 
478*61046927SAndroid Build Coastguard Worker    /* Whether a view of the image with an R8G8 format could be made. */
479*61046927SAndroid Build Coastguard Worker    bool has_r8g8 = tu_is_r8g8(vk_format_to_pipe_format(image->vk.format));
480*61046927SAndroid Build Coastguard Worker 
481*61046927SAndroid Build Coastguard Worker    /* With AHB, we could be asked to create an image with VK_IMAGE_TILING_LINEAR
482*61046927SAndroid Build Coastguard Worker     * but gralloc doesn't know this.  So if we are explicitly told that it is
483*61046927SAndroid Build Coastguard Worker     * UBWC, then override how the image was created.
484*61046927SAndroid Build Coastguard Worker     */
485*61046927SAndroid Build Coastguard Worker    if (modifier == DRM_FORMAT_MOD_QCOM_COMPRESSED) {
486*61046927SAndroid Build Coastguard Worker       assert(!image->force_linear_tile);
487*61046927SAndroid Build Coastguard Worker       image->ubwc_enabled = true;
488*61046927SAndroid Build Coastguard Worker    }
489*61046927SAndroid Build Coastguard Worker 
490*61046927SAndroid Build Coastguard Worker    /* Non-UBWC tiled R8G8 is probably buggy since media formats are always
491*61046927SAndroid Build Coastguard Worker     * either linear or UBWC. There is no simple test to reproduce the bug.
492*61046927SAndroid Build Coastguard Worker     * However it was observed in the wild leading to an unrecoverable hang
493*61046927SAndroid Build Coastguard Worker     * on a650/a660.
494*61046927SAndroid Build Coastguard Worker     */
495*61046927SAndroid Build Coastguard Worker    if (has_r8g8 && tile_mode == TILE6_3 && !image->ubwc_enabled) {
496*61046927SAndroid Build Coastguard Worker       tile_mode = TILE6_LINEAR;
497*61046927SAndroid Build Coastguard Worker    }
498*61046927SAndroid Build Coastguard Worker 
499*61046927SAndroid Build Coastguard Worker    for (uint32_t i = 0; i < tu6_plane_count(image->vk.format); i++) {
500*61046927SAndroid Build Coastguard Worker       struct fdl_layout *layout = &image->layout[i];
501*61046927SAndroid Build Coastguard Worker       enum pipe_format format = tu6_plane_format(image->vk.format, i);
502*61046927SAndroid Build Coastguard Worker       uint32_t width0 = vk_format_get_plane_width(image->vk.format, i, image->vk.extent.width);
503*61046927SAndroid Build Coastguard Worker       uint32_t height0 = vk_format_get_plane_height(image->vk.format, i, image->vk.extent.height);
504*61046927SAndroid Build Coastguard Worker 
505*61046927SAndroid Build Coastguard Worker       if (i == 1 && image->vk.format == VK_FORMAT_D32_SFLOAT_S8_UINT)
506*61046927SAndroid Build Coastguard Worker          /* no UBWC for separate stencil */
507*61046927SAndroid Build Coastguard Worker          image->ubwc_enabled = false;
508*61046927SAndroid Build Coastguard Worker 
509*61046927SAndroid Build Coastguard Worker       struct fdl_explicit_layout plane_layout;
510*61046927SAndroid Build Coastguard Worker 
511*61046927SAndroid Build Coastguard Worker       if (plane_layouts) {
512*61046927SAndroid Build Coastguard Worker          /* only expect simple 2D images for now */
513*61046927SAndroid Build Coastguard Worker          if (image->vk.mip_levels != 1 ||
514*61046927SAndroid Build Coastguard Worker             image->vk.array_layers != 1 ||
515*61046927SAndroid Build Coastguard Worker             image->vk.extent.depth != 1)
516*61046927SAndroid Build Coastguard Worker             return vk_error(device, VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT);
517*61046927SAndroid Build Coastguard Worker 
518*61046927SAndroid Build Coastguard Worker          plane_layout.offset = plane_layouts[i].offset;
519*61046927SAndroid Build Coastguard Worker          plane_layout.pitch = plane_layouts[i].rowPitch;
520*61046927SAndroid Build Coastguard Worker          /* note: use plane_layouts[0].arrayPitch to support array formats */
521*61046927SAndroid Build Coastguard Worker       }
522*61046927SAndroid Build Coastguard Worker 
523*61046927SAndroid Build Coastguard Worker       layout->tile_mode = tile_mode;
524*61046927SAndroid Build Coastguard Worker       layout->ubwc = image->ubwc_enabled;
525*61046927SAndroid Build Coastguard Worker 
526*61046927SAndroid Build Coastguard Worker       if (!fdl6_layout(layout, format,
527*61046927SAndroid Build Coastguard Worker                        image->vk.samples,
528*61046927SAndroid Build Coastguard Worker                        width0, height0,
529*61046927SAndroid Build Coastguard Worker                        image->vk.extent.depth,
530*61046927SAndroid Build Coastguard Worker                        image->vk.mip_levels,
531*61046927SAndroid Build Coastguard Worker                        image->vk.array_layers,
532*61046927SAndroid Build Coastguard Worker                        image->vk.image_type == VK_IMAGE_TYPE_3D,
533*61046927SAndroid Build Coastguard Worker                        plane_layouts ? &plane_layout : NULL)) {
534*61046927SAndroid Build Coastguard Worker          assert(plane_layouts); /* can only fail with explicit layout */
535*61046927SAndroid Build Coastguard Worker          return vk_error(device, VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT);
536*61046927SAndroid Build Coastguard Worker       }
537*61046927SAndroid Build Coastguard Worker 
538*61046927SAndroid Build Coastguard Worker       if (TU_DEBUG(LAYOUT))
539*61046927SAndroid Build Coastguard Worker          fdl_dump_layout(layout);
540*61046927SAndroid Build Coastguard Worker 
541*61046927SAndroid Build Coastguard Worker       /* fdl6_layout can't take explicit offset without explicit pitch
542*61046927SAndroid Build Coastguard Worker        * add offset manually for extra layouts for planes
543*61046927SAndroid Build Coastguard Worker        */
544*61046927SAndroid Build Coastguard Worker       if (!plane_layouts && i > 0) {
545*61046927SAndroid Build Coastguard Worker          uint32_t offset = ALIGN_POT(image->total_size, 4096);
546*61046927SAndroid Build Coastguard Worker          for (int i = 0; i < image->vk.mip_levels; i++) {
547*61046927SAndroid Build Coastguard Worker             layout->slices[i].offset += offset;
548*61046927SAndroid Build Coastguard Worker             layout->ubwc_slices[i].offset += offset;
549*61046927SAndroid Build Coastguard Worker          }
550*61046927SAndroid Build Coastguard Worker          layout->size += offset;
551*61046927SAndroid Build Coastguard Worker       }
552*61046927SAndroid Build Coastguard Worker 
553*61046927SAndroid Build Coastguard Worker       image->total_size = MAX2(image->total_size, layout->size);
554*61046927SAndroid Build Coastguard Worker    }
555*61046927SAndroid Build Coastguard Worker 
556*61046927SAndroid Build Coastguard Worker    const struct util_format_description *desc = util_format_description(image->layout[0].format);
557*61046927SAndroid Build Coastguard Worker    if (util_format_has_depth(desc) && device->use_lrz) {
558*61046927SAndroid Build Coastguard Worker       /* Depth plane is the first one */
559*61046927SAndroid Build Coastguard Worker       struct fdl_layout *layout = &image->layout[0];
560*61046927SAndroid Build Coastguard Worker       unsigned width = layout->width0;
561*61046927SAndroid Build Coastguard Worker       unsigned height = layout->height0;
562*61046927SAndroid Build Coastguard Worker 
563*61046927SAndroid Build Coastguard Worker       /* LRZ buffer is super-sampled */
564*61046927SAndroid Build Coastguard Worker       switch (layout->nr_samples) {
565*61046927SAndroid Build Coastguard Worker       case 4:
566*61046927SAndroid Build Coastguard Worker          width *= 2;
567*61046927SAndroid Build Coastguard Worker          FALLTHROUGH;
568*61046927SAndroid Build Coastguard Worker       case 2:
569*61046927SAndroid Build Coastguard Worker          height *= 2;
570*61046927SAndroid Build Coastguard Worker          break;
571*61046927SAndroid Build Coastguard Worker       default:
572*61046927SAndroid Build Coastguard Worker          break;
573*61046927SAndroid Build Coastguard Worker       }
574*61046927SAndroid Build Coastguard Worker 
575*61046927SAndroid Build Coastguard Worker       unsigned lrz_pitch  = align(DIV_ROUND_UP(width, 8), 32);
576*61046927SAndroid Build Coastguard Worker       unsigned lrz_height = align(DIV_ROUND_UP(height, 8), 16);
577*61046927SAndroid Build Coastguard Worker 
578*61046927SAndroid Build Coastguard Worker       image->lrz_height = lrz_height;
579*61046927SAndroid Build Coastguard Worker       image->lrz_pitch = lrz_pitch;
580*61046927SAndroid Build Coastguard Worker       image->lrz_offset = image->total_size;
581*61046927SAndroid Build Coastguard Worker       unsigned lrz_size = lrz_pitch * lrz_height * sizeof(uint16_t);
582*61046927SAndroid Build Coastguard Worker 
583*61046927SAndroid Build Coastguard Worker       unsigned nblocksx = DIV_ROUND_UP(DIV_ROUND_UP(width, 8), 16);
584*61046927SAndroid Build Coastguard Worker       unsigned nblocksy = DIV_ROUND_UP(DIV_ROUND_UP(height, 8), 4);
585*61046927SAndroid Build Coastguard Worker 
586*61046927SAndroid Build Coastguard Worker       /* Fast-clear buffer is 1bit/block */
587*61046927SAndroid Build Coastguard Worker       unsigned lrz_fc_size = DIV_ROUND_UP(nblocksx * nblocksy, 8);
588*61046927SAndroid Build Coastguard Worker 
589*61046927SAndroid Build Coastguard Worker       /* Fast-clear buffer cannot be larger than 512 bytes on A6XX and 1024 bytes on A7XX (HW limitation) */
590*61046927SAndroid Build Coastguard Worker       image->has_lrz_fc =
591*61046927SAndroid Build Coastguard Worker          device->physical_device->info->a6xx.enable_lrz_fast_clear &&
592*61046927SAndroid Build Coastguard Worker          lrz_fc_size <= fd_lrzfc_layout<CHIP>::FC_SIZE &&
593*61046927SAndroid Build Coastguard Worker          !TU_DEBUG(NOLRZFC);
594*61046927SAndroid Build Coastguard Worker 
595*61046927SAndroid Build Coastguard Worker       if (image->has_lrz_fc || device->physical_device->info->a6xx.has_lrz_dir_tracking) {
596*61046927SAndroid Build Coastguard Worker          image->lrz_fc_offset = image->total_size + lrz_size;
597*61046927SAndroid Build Coastguard Worker          lrz_size += sizeof(fd_lrzfc_layout<CHIP>);
598*61046927SAndroid Build Coastguard Worker       }
599*61046927SAndroid Build Coastguard Worker 
600*61046927SAndroid Build Coastguard Worker       image->total_size += lrz_size;
601*61046927SAndroid Build Coastguard Worker    } else {
602*61046927SAndroid Build Coastguard Worker       image->lrz_height = 0;
603*61046927SAndroid Build Coastguard Worker    }
604*61046927SAndroid Build Coastguard Worker 
605*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
606*61046927SAndroid Build Coastguard Worker }
607*61046927SAndroid Build Coastguard Worker TU_GENX(tu_image_update_layout);
608*61046927SAndroid Build Coastguard Worker 
609*61046927SAndroid Build Coastguard Worker static VkResult
tu_image_init(struct tu_device * device,struct tu_image * image,const VkImageCreateInfo * pCreateInfo)610*61046927SAndroid Build Coastguard Worker tu_image_init(struct tu_device *device, struct tu_image *image,
611*61046927SAndroid Build Coastguard Worker               const VkImageCreateInfo *pCreateInfo)
612*61046927SAndroid Build Coastguard Worker {
613*61046927SAndroid Build Coastguard Worker    image->ubwc_enabled = true;
614*61046927SAndroid Build Coastguard Worker 
615*61046927SAndroid Build Coastguard Worker    /* use linear tiling if requested */
616*61046927SAndroid Build Coastguard Worker    if (pCreateInfo->tiling == VK_IMAGE_TILING_LINEAR) {
617*61046927SAndroid Build Coastguard Worker       image->force_linear_tile = true;
618*61046927SAndroid Build Coastguard Worker    }
619*61046927SAndroid Build Coastguard Worker 
620*61046927SAndroid Build Coastguard Worker    /* Force linear tiling for formats with "fake" optimalTilingFeatures */
621*61046927SAndroid Build Coastguard Worker    if (!tiling_possible(image->vk.format)) {
622*61046927SAndroid Build Coastguard Worker       image->force_linear_tile = true;
623*61046927SAndroid Build Coastguard Worker    }
624*61046927SAndroid Build Coastguard Worker 
625*61046927SAndroid Build Coastguard Worker    /* No sense in tiling a 1D image, you'd just waste space and cache locality. */
626*61046927SAndroid Build Coastguard Worker    if (pCreateInfo->imageType == VK_IMAGE_TYPE_1D) {
627*61046927SAndroid Build Coastguard Worker       image->force_linear_tile = true;
628*61046927SAndroid Build Coastguard Worker    }
629*61046927SAndroid Build Coastguard Worker 
630*61046927SAndroid Build Coastguard Worker    /* Fragment density maps are sampled on the CPU and we don't support
631*61046927SAndroid Build Coastguard Worker     * sampling tiled images on the CPU or UBWC at the moment.
632*61046927SAndroid Build Coastguard Worker     */
633*61046927SAndroid Build Coastguard Worker    if (pCreateInfo->usage & VK_IMAGE_USAGE_FRAGMENT_DENSITY_MAP_BIT_EXT) {
634*61046927SAndroid Build Coastguard Worker       image->force_linear_tile = true;
635*61046927SAndroid Build Coastguard Worker    }
636*61046927SAndroid Build Coastguard Worker 
637*61046927SAndroid Build Coastguard Worker    if (image->force_linear_tile ||
638*61046927SAndroid Build Coastguard Worker        !ubwc_possible(device, image->vk.format, pCreateInfo->imageType,
639*61046927SAndroid Build Coastguard Worker                       pCreateInfo->usage, image->vk.stencil_usage,
640*61046927SAndroid Build Coastguard Worker                       device->physical_device->info, pCreateInfo->samples,
641*61046927SAndroid Build Coastguard Worker                       device->use_z24uint_s8uint))
642*61046927SAndroid Build Coastguard Worker       image->ubwc_enabled = false;
643*61046927SAndroid Build Coastguard Worker 
644*61046927SAndroid Build Coastguard Worker    bool fmt_list_has_swaps = false;
645*61046927SAndroid Build Coastguard Worker    /* Mutable images can be reinterpreted as any other compatible format.
646*61046927SAndroid Build Coastguard Worker     * This is a problem with UBWC (compression for different formats is different),
647*61046927SAndroid Build Coastguard Worker     * but also tiling ("swap" affects how tiled formats are stored in memory)
648*61046927SAndroid Build Coastguard Worker     * Depth and stencil formats cannot be reintepreted as another format, and
649*61046927SAndroid Build Coastguard Worker     * cannot be linear with sysmem rendering, so don't fall back for those.
650*61046927SAndroid Build Coastguard Worker     *
651*61046927SAndroid Build Coastguard Worker     * TODO:
652*61046927SAndroid Build Coastguard Worker     * - if the fmt_list contains only formats which are swapped, but compatible
653*61046927SAndroid Build Coastguard Worker     *   with each other (B8G8R8A8_UNORM and B8G8R8A8_UINT for example), then
654*61046927SAndroid Build Coastguard Worker     *   tiling is still possible
655*61046927SAndroid Build Coastguard Worker     * - figure out which UBWC compressions are compatible to keep it enabled
656*61046927SAndroid Build Coastguard Worker     */
657*61046927SAndroid Build Coastguard Worker    if ((pCreateInfo->flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT) &&
658*61046927SAndroid Build Coastguard Worker        !vk_format_is_depth_or_stencil(image->vk.format)) {
659*61046927SAndroid Build Coastguard Worker       const VkImageFormatListCreateInfo *fmt_list =
660*61046927SAndroid Build Coastguard Worker          vk_find_struct_const(pCreateInfo->pNext, IMAGE_FORMAT_LIST_CREATE_INFO);
661*61046927SAndroid Build Coastguard Worker       fmt_list_has_swaps = format_list_has_swaps(fmt_list);
662*61046927SAndroid Build Coastguard Worker       if (!tu6_mutable_format_list_ubwc_compatible(device->physical_device->info,
663*61046927SAndroid Build Coastguard Worker                                                    fmt_list)) {
664*61046927SAndroid Build Coastguard Worker          bool mutable_ubwc_fc = device->physical_device->info->a7xx.ubwc_all_formats_compatible;
665*61046927SAndroid Build Coastguard Worker          if (image->ubwc_enabled && !mutable_ubwc_fc) {
666*61046927SAndroid Build Coastguard Worker             if (fmt_list && fmt_list->viewFormatCount == 2) {
667*61046927SAndroid Build Coastguard Worker                perf_debug(
668*61046927SAndroid Build Coastguard Worker                   device,
669*61046927SAndroid Build Coastguard Worker                   "Disabling UBWC on %dx%d %s resource due to mutable formats "
670*61046927SAndroid Build Coastguard Worker                   "(fmt list %s, %s)",
671*61046927SAndroid Build Coastguard Worker                   image->vk.extent.width, image->vk.extent.height,
672*61046927SAndroid Build Coastguard Worker                   util_format_name(vk_format_to_pipe_format(image->vk.format)),
673*61046927SAndroid Build Coastguard Worker                   util_format_name(vk_format_to_pipe_format(fmt_list->pViewFormats[0])),
674*61046927SAndroid Build Coastguard Worker                   util_format_name(vk_format_to_pipe_format(fmt_list->pViewFormats[1])));
675*61046927SAndroid Build Coastguard Worker             } else {
676*61046927SAndroid Build Coastguard Worker                perf_debug(
677*61046927SAndroid Build Coastguard Worker                   device,
678*61046927SAndroid Build Coastguard Worker                   "Disabling UBWC on %dx%d %s resource due to mutable formats "
679*61046927SAndroid Build Coastguard Worker                   "(fmt list %s)",
680*61046927SAndroid Build Coastguard Worker                   image->vk.extent.width, image->vk.extent.height,
681*61046927SAndroid Build Coastguard Worker                   util_format_name(vk_format_to_pipe_format(image->vk.format)),
682*61046927SAndroid Build Coastguard Worker                   fmt_list ? "present" : "missing");
683*61046927SAndroid Build Coastguard Worker             }
684*61046927SAndroid Build Coastguard Worker             image->ubwc_enabled = false;
685*61046927SAndroid Build Coastguard Worker          }
686*61046927SAndroid Build Coastguard Worker 
687*61046927SAndroid Build Coastguard Worker          bool r8g8_r16 = format_list_reinterprets_r8g8_r16(vk_format_to_pipe_format(image->vk.format), fmt_list);
688*61046927SAndroid Build Coastguard Worker 
689*61046927SAndroid Build Coastguard Worker          /* A750+ TODO: Correctly handle swaps when copying mutable images.
690*61046927SAndroid Build Coastguard Worker           * We should be able to support UBWC for mutable images with swaps.
691*61046927SAndroid Build Coastguard Worker           */
692*61046927SAndroid Build Coastguard Worker          if ((r8g8_r16 && !mutable_ubwc_fc) || fmt_list_has_swaps) {
693*61046927SAndroid Build Coastguard Worker             image->ubwc_enabled = false;
694*61046927SAndroid Build Coastguard Worker             image->force_linear_tile = true;
695*61046927SAndroid Build Coastguard Worker          }
696*61046927SAndroid Build Coastguard Worker 
697*61046927SAndroid Build Coastguard Worker          image->ubwc_fc_mutable = image->ubwc_enabled && mutable_ubwc_fc;
698*61046927SAndroid Build Coastguard Worker       }
699*61046927SAndroid Build Coastguard Worker    }
700*61046927SAndroid Build Coastguard Worker 
701*61046927SAndroid Build Coastguard Worker    if (TU_DEBUG(NOUBWC)) {
702*61046927SAndroid Build Coastguard Worker       image->ubwc_enabled = false;
703*61046927SAndroid Build Coastguard Worker    }
704*61046927SAndroid Build Coastguard Worker 
705*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
706*61046927SAndroid Build Coastguard Worker }
707*61046927SAndroid Build Coastguard Worker 
708*61046927SAndroid Build Coastguard Worker VKAPI_ATTR VkResult VKAPI_CALL
tu_CreateImage(VkDevice _device,const VkImageCreateInfo * pCreateInfo,const VkAllocationCallbacks * alloc,VkImage * pImage)709*61046927SAndroid Build Coastguard Worker tu_CreateImage(VkDevice _device,
710*61046927SAndroid Build Coastguard Worker                const VkImageCreateInfo *pCreateInfo,
711*61046927SAndroid Build Coastguard Worker                const VkAllocationCallbacks *alloc,
712*61046927SAndroid Build Coastguard Worker                VkImage *pImage)
713*61046927SAndroid Build Coastguard Worker {
714*61046927SAndroid Build Coastguard Worker    uint64_t modifier = DRM_FORMAT_MOD_INVALID;
715*61046927SAndroid Build Coastguard Worker    const VkSubresourceLayout *plane_layouts = NULL;
716*61046927SAndroid Build Coastguard Worker    VkResult result;
717*61046927SAndroid Build Coastguard Worker 
718*61046927SAndroid Build Coastguard Worker    VK_FROM_HANDLE(tu_device, device, _device);
719*61046927SAndroid Build Coastguard Worker 
720*61046927SAndroid Build Coastguard Worker #ifdef TU_USE_WSI_PLATFORM
721*61046927SAndroid Build Coastguard Worker    /* Ignore swapchain creation info on Android. Since we don't have an
722*61046927SAndroid Build Coastguard Worker     * implementation in Mesa, we're guaranteed to access an Android object
723*61046927SAndroid Build Coastguard Worker     * incorrectly.
724*61046927SAndroid Build Coastguard Worker     */
725*61046927SAndroid Build Coastguard Worker    const VkImageSwapchainCreateInfoKHR *swapchain_info =
726*61046927SAndroid Build Coastguard Worker       vk_find_struct_const(pCreateInfo->pNext, IMAGE_SWAPCHAIN_CREATE_INFO_KHR);
727*61046927SAndroid Build Coastguard Worker    if (swapchain_info && swapchain_info->swapchain != VK_NULL_HANDLE) {
728*61046927SAndroid Build Coastguard Worker       return wsi_common_create_swapchain_image(device->physical_device->vk.wsi_device,
729*61046927SAndroid Build Coastguard Worker                                                pCreateInfo,
730*61046927SAndroid Build Coastguard Worker                                                swapchain_info->swapchain,
731*61046927SAndroid Build Coastguard Worker                                                pImage);
732*61046927SAndroid Build Coastguard Worker    }
733*61046927SAndroid Build Coastguard Worker #endif
734*61046927SAndroid Build Coastguard Worker 
735*61046927SAndroid Build Coastguard Worker    struct tu_image *image = (struct tu_image *)
736*61046927SAndroid Build Coastguard Worker       vk_image_create(&device->vk, pCreateInfo, alloc, sizeof(*image));
737*61046927SAndroid Build Coastguard Worker 
738*61046927SAndroid Build Coastguard Worker    if (!image)
739*61046927SAndroid Build Coastguard Worker       return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
740*61046927SAndroid Build Coastguard Worker 
741*61046927SAndroid Build Coastguard Worker    if (pCreateInfo->tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT) {
742*61046927SAndroid Build Coastguard Worker       const VkImageDrmFormatModifierListCreateInfoEXT *mod_info =
743*61046927SAndroid Build Coastguard Worker          vk_find_struct_const(pCreateInfo->pNext,
744*61046927SAndroid Build Coastguard Worker                               IMAGE_DRM_FORMAT_MODIFIER_LIST_CREATE_INFO_EXT);
745*61046927SAndroid Build Coastguard Worker       const VkImageDrmFormatModifierExplicitCreateInfoEXT *drm_explicit_info =
746*61046927SAndroid Build Coastguard Worker          vk_find_struct_const(pCreateInfo->pNext,
747*61046927SAndroid Build Coastguard Worker                               IMAGE_DRM_FORMAT_MODIFIER_EXPLICIT_CREATE_INFO_EXT);
748*61046927SAndroid Build Coastguard Worker 
749*61046927SAndroid Build Coastguard Worker       assert(mod_info || drm_explicit_info);
750*61046927SAndroid Build Coastguard Worker 
751*61046927SAndroid Build Coastguard Worker       if (mod_info) {
752*61046927SAndroid Build Coastguard Worker          modifier = DRM_FORMAT_MOD_LINEAR;
753*61046927SAndroid Build Coastguard Worker          for (unsigned i = 0; i < mod_info->drmFormatModifierCount; i++) {
754*61046927SAndroid Build Coastguard Worker             if (mod_info->pDrmFormatModifiers[i] == DRM_FORMAT_MOD_QCOM_COMPRESSED)
755*61046927SAndroid Build Coastguard Worker                modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED;
756*61046927SAndroid Build Coastguard Worker          }
757*61046927SAndroid Build Coastguard Worker       } else {
758*61046927SAndroid Build Coastguard Worker          modifier = drm_explicit_info->drmFormatModifier;
759*61046927SAndroid Build Coastguard Worker          assert(modifier == DRM_FORMAT_MOD_LINEAR ||
760*61046927SAndroid Build Coastguard Worker                 modifier == DRM_FORMAT_MOD_QCOM_COMPRESSED);
761*61046927SAndroid Build Coastguard Worker          plane_layouts = drm_explicit_info->pPlaneLayouts;
762*61046927SAndroid Build Coastguard Worker       }
763*61046927SAndroid Build Coastguard Worker    } else {
764*61046927SAndroid Build Coastguard Worker       const struct wsi_image_create_info *wsi_info =
765*61046927SAndroid Build Coastguard Worker          vk_find_struct_const(pCreateInfo->pNext, WSI_IMAGE_CREATE_INFO_MESA);
766*61046927SAndroid Build Coastguard Worker       if (wsi_info && wsi_info->scanout)
767*61046927SAndroid Build Coastguard Worker          modifier = DRM_FORMAT_MOD_LINEAR;
768*61046927SAndroid Build Coastguard Worker    }
769*61046927SAndroid Build Coastguard Worker 
770*61046927SAndroid Build Coastguard Worker    /* This section is removed by the optimizer for non-ANDROID builds */
771*61046927SAndroid Build Coastguard Worker    VkImageDrmFormatModifierExplicitCreateInfoEXT eci;
772*61046927SAndroid Build Coastguard Worker    VkSubresourceLayout a_plane_layouts[TU_MAX_PLANE_COUNT];
773*61046927SAndroid Build Coastguard Worker    if (vk_image_is_android_native_buffer(&image->vk)) {
774*61046927SAndroid Build Coastguard Worker       result = vk_android_get_anb_layout(
775*61046927SAndroid Build Coastguard Worker          pCreateInfo, &eci, a_plane_layouts, TU_MAX_PLANE_COUNT);
776*61046927SAndroid Build Coastguard Worker       if (result != VK_SUCCESS)
777*61046927SAndroid Build Coastguard Worker          goto fail;
778*61046927SAndroid Build Coastguard Worker 
779*61046927SAndroid Build Coastguard Worker       plane_layouts = a_plane_layouts;
780*61046927SAndroid Build Coastguard Worker       modifier = eci.drmFormatModifier;
781*61046927SAndroid Build Coastguard Worker    }
782*61046927SAndroid Build Coastguard Worker 
783*61046927SAndroid Build Coastguard Worker    result = tu_image_init(device, image, pCreateInfo);
784*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
785*61046927SAndroid Build Coastguard Worker       goto fail;
786*61046927SAndroid Build Coastguard Worker 
787*61046927SAndroid Build Coastguard Worker    /* This section is removed by the optimizer for non-ANDROID builds */
788*61046927SAndroid Build Coastguard Worker    if (vk_image_is_android_hardware_buffer(&image->vk)) {
789*61046927SAndroid Build Coastguard Worker       /* At this time, an AHB handle is not yet provided.
790*61046927SAndroid Build Coastguard Worker        * Image layout will be filled up during vkBindImageMemory2
791*61046927SAndroid Build Coastguard Worker        */
792*61046927SAndroid Build Coastguard Worker       *pImage = tu_image_to_handle(image);
793*61046927SAndroid Build Coastguard Worker       return VK_SUCCESS;
794*61046927SAndroid Build Coastguard Worker    }
795*61046927SAndroid Build Coastguard Worker 
796*61046927SAndroid Build Coastguard Worker    result = TU_CALLX(device, tu_image_update_layout)(device, image, modifier,
797*61046927SAndroid Build Coastguard Worker                                                     plane_layouts);
798*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
799*61046927SAndroid Build Coastguard Worker       goto fail;
800*61046927SAndroid Build Coastguard Worker 
801*61046927SAndroid Build Coastguard Worker    /* This section is removed by the optimizer for non-ANDROID builds */
802*61046927SAndroid Build Coastguard Worker    if (vk_image_is_android_native_buffer(&image->vk)) {
803*61046927SAndroid Build Coastguard Worker       result = vk_android_import_anb(&device->vk, pCreateInfo, alloc,
804*61046927SAndroid Build Coastguard Worker                                      &image->vk);
805*61046927SAndroid Build Coastguard Worker       if (result != VK_SUCCESS)
806*61046927SAndroid Build Coastguard Worker          goto fail;
807*61046927SAndroid Build Coastguard Worker    }
808*61046927SAndroid Build Coastguard Worker 
809*61046927SAndroid Build Coastguard Worker    TU_RMV(image_create, device, image);
810*61046927SAndroid Build Coastguard Worker 
811*61046927SAndroid Build Coastguard Worker #ifdef HAVE_PERFETTO
812*61046927SAndroid Build Coastguard Worker    tu_perfetto_log_create_image(device, image);
813*61046927SAndroid Build Coastguard Worker #endif
814*61046927SAndroid Build Coastguard Worker 
815*61046927SAndroid Build Coastguard Worker    *pImage = tu_image_to_handle(image);
816*61046927SAndroid Build Coastguard Worker 
817*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
818*61046927SAndroid Build Coastguard Worker fail:
819*61046927SAndroid Build Coastguard Worker    vk_image_destroy(&device->vk, alloc, &image->vk);
820*61046927SAndroid Build Coastguard Worker    return result;
821*61046927SAndroid Build Coastguard Worker }
822*61046927SAndroid Build Coastguard Worker 
823*61046927SAndroid Build Coastguard Worker VKAPI_ATTR void VKAPI_CALL
tu_DestroyImage(VkDevice _device,VkImage _image,const VkAllocationCallbacks * pAllocator)824*61046927SAndroid Build Coastguard Worker tu_DestroyImage(VkDevice _device,
825*61046927SAndroid Build Coastguard Worker                 VkImage _image,
826*61046927SAndroid Build Coastguard Worker                 const VkAllocationCallbacks *pAllocator)
827*61046927SAndroid Build Coastguard Worker {
828*61046927SAndroid Build Coastguard Worker    VK_FROM_HANDLE(tu_device, device, _device);
829*61046927SAndroid Build Coastguard Worker    VK_FROM_HANDLE(tu_image, image, _image);
830*61046927SAndroid Build Coastguard Worker    struct tu_instance *instance = device->physical_device->instance;
831*61046927SAndroid Build Coastguard Worker 
832*61046927SAndroid Build Coastguard Worker    if (!image)
833*61046927SAndroid Build Coastguard Worker       return;
834*61046927SAndroid Build Coastguard Worker 
835*61046927SAndroid Build Coastguard Worker    TU_RMV(image_destroy, device, image);
836*61046927SAndroid Build Coastguard Worker 
837*61046927SAndroid Build Coastguard Worker #ifdef HAVE_PERFETTO
838*61046927SAndroid Build Coastguard Worker    tu_perfetto_log_destroy_image(device, image);
839*61046927SAndroid Build Coastguard Worker #endif
840*61046927SAndroid Build Coastguard Worker 
841*61046927SAndroid Build Coastguard Worker    if (image->iova)
842*61046927SAndroid Build Coastguard Worker       vk_address_binding_report(&instance->vk, &image->vk.base,
843*61046927SAndroid Build Coastguard Worker                                 image->iova, image->total_size,
844*61046927SAndroid Build Coastguard Worker                                 VK_DEVICE_ADDRESS_BINDING_TYPE_UNBIND_EXT);
845*61046927SAndroid Build Coastguard Worker 
846*61046927SAndroid Build Coastguard Worker    vk_image_destroy(&device->vk, pAllocator, &image->vk);
847*61046927SAndroid Build Coastguard Worker }
848*61046927SAndroid Build Coastguard Worker 
849*61046927SAndroid Build Coastguard Worker VKAPI_ATTR VkResult VKAPI_CALL
tu_BindImageMemory2(VkDevice _device,uint32_t bindInfoCount,const VkBindImageMemoryInfo * pBindInfos)850*61046927SAndroid Build Coastguard Worker tu_BindImageMemory2(VkDevice _device,
851*61046927SAndroid Build Coastguard Worker                     uint32_t bindInfoCount,
852*61046927SAndroid Build Coastguard Worker                     const VkBindImageMemoryInfo *pBindInfos)
853*61046927SAndroid Build Coastguard Worker {
854*61046927SAndroid Build Coastguard Worker    VK_FROM_HANDLE(tu_device, device, _device);
855*61046927SAndroid Build Coastguard Worker    struct tu_instance *instance = device->physical_device->instance;
856*61046927SAndroid Build Coastguard Worker 
857*61046927SAndroid Build Coastguard Worker    for (uint32_t i = 0; i < bindInfoCount; ++i) {
858*61046927SAndroid Build Coastguard Worker       VK_FROM_HANDLE(tu_image, image, pBindInfos[i].image);
859*61046927SAndroid Build Coastguard Worker       VK_FROM_HANDLE(tu_device_memory, mem, pBindInfos[i].memory);
860*61046927SAndroid Build Coastguard Worker 
861*61046927SAndroid Build Coastguard Worker       /* Ignore this struct on Android, we cannot access swapchain structures there. */
862*61046927SAndroid Build Coastguard Worker #ifdef TU_USE_WSI_PLATFORM
863*61046927SAndroid Build Coastguard Worker       const VkBindImageMemorySwapchainInfoKHR *swapchain_info =
864*61046927SAndroid Build Coastguard Worker          vk_find_struct_const(pBindInfos[i].pNext, BIND_IMAGE_MEMORY_SWAPCHAIN_INFO_KHR);
865*61046927SAndroid Build Coastguard Worker 
866*61046927SAndroid Build Coastguard Worker       if (swapchain_info && swapchain_info->swapchain != VK_NULL_HANDLE) {
867*61046927SAndroid Build Coastguard Worker          VkImage _wsi_image = wsi_common_get_image(swapchain_info->swapchain,
868*61046927SAndroid Build Coastguard Worker                                                    swapchain_info->imageIndex);
869*61046927SAndroid Build Coastguard Worker          VK_FROM_HANDLE(tu_image, wsi_img, _wsi_image);
870*61046927SAndroid Build Coastguard Worker 
871*61046927SAndroid Build Coastguard Worker          image->bo = wsi_img->bo;
872*61046927SAndroid Build Coastguard Worker          image->map = NULL;
873*61046927SAndroid Build Coastguard Worker          image->iova = wsi_img->iova;
874*61046927SAndroid Build Coastguard Worker 
875*61046927SAndroid Build Coastguard Worker          TU_RMV(image_bind, device, image);
876*61046927SAndroid Build Coastguard Worker 
877*61046927SAndroid Build Coastguard Worker          vk_address_binding_report(&instance->vk, &image->vk.base,
878*61046927SAndroid Build Coastguard Worker                                    image->iova, image->total_size,
879*61046927SAndroid Build Coastguard Worker                                    VK_DEVICE_ADDRESS_BINDING_TYPE_BIND_EXT);
880*61046927SAndroid Build Coastguard Worker 
881*61046927SAndroid Build Coastguard Worker          continue;
882*61046927SAndroid Build Coastguard Worker       }
883*61046927SAndroid Build Coastguard Worker #endif
884*61046927SAndroid Build Coastguard Worker 
885*61046927SAndroid Build Coastguard Worker       const VkBindMemoryStatusKHR *status =
886*61046927SAndroid Build Coastguard Worker          vk_find_struct_const(pBindInfos[i].pNext, BIND_MEMORY_STATUS_KHR);
887*61046927SAndroid Build Coastguard Worker       if (status)
888*61046927SAndroid Build Coastguard Worker          *status->pResult = VK_SUCCESS;
889*61046927SAndroid Build Coastguard Worker 
890*61046927SAndroid Build Coastguard Worker       if (mem) {
891*61046927SAndroid Build Coastguard Worker          VkResult result;
892*61046927SAndroid Build Coastguard Worker          if (vk_image_is_android_hardware_buffer(&image->vk)) {
893*61046927SAndroid Build Coastguard Worker             VkImageDrmFormatModifierExplicitCreateInfoEXT eci;
894*61046927SAndroid Build Coastguard Worker             VkSubresourceLayout a_plane_layouts[TU_MAX_PLANE_COUNT];
895*61046927SAndroid Build Coastguard Worker             result = vk_android_get_ahb_layout(mem->vk.ahardware_buffer,
896*61046927SAndroid Build Coastguard Worker                                             &eci, a_plane_layouts,
897*61046927SAndroid Build Coastguard Worker                                             TU_MAX_PLANE_COUNT);
898*61046927SAndroid Build Coastguard Worker             if (result != VK_SUCCESS) {
899*61046927SAndroid Build Coastguard Worker                if (status)
900*61046927SAndroid Build Coastguard Worker                   *status->pResult = result;
901*61046927SAndroid Build Coastguard Worker                return result;
902*61046927SAndroid Build Coastguard Worker             }
903*61046927SAndroid Build Coastguard Worker 
904*61046927SAndroid Build Coastguard Worker             result = TU_CALLX(device, tu_image_update_layout)(device, image,
905*61046927SAndroid Build Coastguard Worker                                                               eci.drmFormatModifier, a_plane_layouts);
906*61046927SAndroid Build Coastguard Worker             if (result != VK_SUCCESS) {
907*61046927SAndroid Build Coastguard Worker                if (status)
908*61046927SAndroid Build Coastguard Worker                   *status->pResult = result;
909*61046927SAndroid Build Coastguard Worker                return result;
910*61046927SAndroid Build Coastguard Worker             }
911*61046927SAndroid Build Coastguard Worker          }
912*61046927SAndroid Build Coastguard Worker          image->bo = mem->bo;
913*61046927SAndroid Build Coastguard Worker          image->iova = mem->bo->iova + pBindInfos[i].memoryOffset;
914*61046927SAndroid Build Coastguard Worker 
915*61046927SAndroid Build Coastguard Worker          if (image->vk.usage & VK_IMAGE_USAGE_FRAGMENT_DENSITY_MAP_BIT_EXT) {
916*61046927SAndroid Build Coastguard Worker             if (!mem->bo->map) {
917*61046927SAndroid Build Coastguard Worker                result = tu_bo_map(device, mem->bo, NULL);
918*61046927SAndroid Build Coastguard Worker                if (result != VK_SUCCESS) {
919*61046927SAndroid Build Coastguard Worker                   if (status)
920*61046927SAndroid Build Coastguard Worker                      *status->pResult = result;
921*61046927SAndroid Build Coastguard Worker                   return result;
922*61046927SAndroid Build Coastguard Worker                }
923*61046927SAndroid Build Coastguard Worker             }
924*61046927SAndroid Build Coastguard Worker 
925*61046927SAndroid Build Coastguard Worker             image->map = (char *)mem->bo->map + pBindInfos[i].memoryOffset;
926*61046927SAndroid Build Coastguard Worker          } else {
927*61046927SAndroid Build Coastguard Worker             image->map = NULL;
928*61046927SAndroid Build Coastguard Worker          }
929*61046927SAndroid Build Coastguard Worker #ifdef HAVE_PERFETTO
930*61046927SAndroid Build Coastguard Worker          tu_perfetto_log_bind_image(device, image);
931*61046927SAndroid Build Coastguard Worker #endif
932*61046927SAndroid Build Coastguard Worker       } else {
933*61046927SAndroid Build Coastguard Worker          image->bo = NULL;
934*61046927SAndroid Build Coastguard Worker          image->map = NULL;
935*61046927SAndroid Build Coastguard Worker          image->iova = 0;
936*61046927SAndroid Build Coastguard Worker       }
937*61046927SAndroid Build Coastguard Worker 
938*61046927SAndroid Build Coastguard Worker       TU_RMV(image_bind, device, image);
939*61046927SAndroid Build Coastguard Worker 
940*61046927SAndroid Build Coastguard Worker       vk_address_binding_report(&instance->vk, &image->vk.base,
941*61046927SAndroid Build Coastguard Worker                                 image->iova, image->total_size,
942*61046927SAndroid Build Coastguard Worker                                 VK_DEVICE_ADDRESS_BINDING_TYPE_BIND_EXT);
943*61046927SAndroid Build Coastguard Worker    }
944*61046927SAndroid Build Coastguard Worker 
945*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
946*61046927SAndroid Build Coastguard Worker }
947*61046927SAndroid Build Coastguard Worker 
948*61046927SAndroid Build Coastguard Worker static void
tu_get_image_memory_requirements(struct tu_device * dev,struct tu_image * image,VkMemoryRequirements2 * pMemoryRequirements)949*61046927SAndroid Build Coastguard Worker tu_get_image_memory_requirements(struct tu_device *dev, struct tu_image *image,
950*61046927SAndroid Build Coastguard Worker                                  VkMemoryRequirements2 *pMemoryRequirements)
951*61046927SAndroid Build Coastguard Worker {
952*61046927SAndroid Build Coastguard Worker    pMemoryRequirements->memoryRequirements = (VkMemoryRequirements) {
953*61046927SAndroid Build Coastguard Worker       .size = image->total_size,
954*61046927SAndroid Build Coastguard Worker       .alignment = image->layout[0].base_align,
955*61046927SAndroid Build Coastguard Worker       .memoryTypeBits = (1 << dev->physical_device->memory.type_count) - 1,
956*61046927SAndroid Build Coastguard Worker    };
957*61046927SAndroid Build Coastguard Worker 
958*61046927SAndroid Build Coastguard Worker    vk_foreach_struct(ext, pMemoryRequirements->pNext) {
959*61046927SAndroid Build Coastguard Worker       switch (ext->sType) {
960*61046927SAndroid Build Coastguard Worker       case VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS: {
961*61046927SAndroid Build Coastguard Worker          VkMemoryDedicatedRequirements *req =
962*61046927SAndroid Build Coastguard Worker             (VkMemoryDedicatedRequirements *) ext;
963*61046927SAndroid Build Coastguard Worker          req->requiresDedicatedAllocation =
964*61046927SAndroid Build Coastguard Worker             image->vk.external_handle_types != 0;
965*61046927SAndroid Build Coastguard Worker          req->prefersDedicatedAllocation = req->requiresDedicatedAllocation;
966*61046927SAndroid Build Coastguard Worker          break;
967*61046927SAndroid Build Coastguard Worker       }
968*61046927SAndroid Build Coastguard Worker       default:
969*61046927SAndroid Build Coastguard Worker          break;
970*61046927SAndroid Build Coastguard Worker       }
971*61046927SAndroid Build Coastguard Worker    }
972*61046927SAndroid Build Coastguard Worker }
973*61046927SAndroid Build Coastguard Worker 
974*61046927SAndroid Build Coastguard Worker VKAPI_ATTR void VKAPI_CALL
tu_GetImageMemoryRequirements2(VkDevice _device,const VkImageMemoryRequirementsInfo2 * pInfo,VkMemoryRequirements2 * pMemoryRequirements)975*61046927SAndroid Build Coastguard Worker tu_GetImageMemoryRequirements2(VkDevice _device,
976*61046927SAndroid Build Coastguard Worker                                const VkImageMemoryRequirementsInfo2 *pInfo,
977*61046927SAndroid Build Coastguard Worker                                VkMemoryRequirements2 *pMemoryRequirements)
978*61046927SAndroid Build Coastguard Worker {
979*61046927SAndroid Build Coastguard Worker    VK_FROM_HANDLE(tu_device, device, _device);
980*61046927SAndroid Build Coastguard Worker    VK_FROM_HANDLE(tu_image, image, pInfo->image);
981*61046927SAndroid Build Coastguard Worker 
982*61046927SAndroid Build Coastguard Worker    tu_get_image_memory_requirements(device, image, pMemoryRequirements);
983*61046927SAndroid Build Coastguard Worker }
984*61046927SAndroid Build Coastguard Worker 
985*61046927SAndroid Build Coastguard Worker VKAPI_ATTR void VKAPI_CALL
tu_GetImageSparseMemoryRequirements2(VkDevice device,const VkImageSparseMemoryRequirementsInfo2 * pInfo,uint32_t * pSparseMemoryRequirementCount,VkSparseImageMemoryRequirements2 * pSparseMemoryRequirements)986*61046927SAndroid Build Coastguard Worker tu_GetImageSparseMemoryRequirements2(
987*61046927SAndroid Build Coastguard Worker    VkDevice device,
988*61046927SAndroid Build Coastguard Worker    const VkImageSparseMemoryRequirementsInfo2 *pInfo,
989*61046927SAndroid Build Coastguard Worker    uint32_t *pSparseMemoryRequirementCount,
990*61046927SAndroid Build Coastguard Worker    VkSparseImageMemoryRequirements2 *pSparseMemoryRequirements)
991*61046927SAndroid Build Coastguard Worker {
992*61046927SAndroid Build Coastguard Worker    tu_stub();
993*61046927SAndroid Build Coastguard Worker }
994*61046927SAndroid Build Coastguard Worker 
995*61046927SAndroid Build Coastguard Worker VKAPI_ATTR void VKAPI_CALL
tu_GetDeviceImageMemoryRequirements(VkDevice _device,const VkDeviceImageMemoryRequirements * pInfo,VkMemoryRequirements2 * pMemoryRequirements)996*61046927SAndroid Build Coastguard Worker tu_GetDeviceImageMemoryRequirements(
997*61046927SAndroid Build Coastguard Worker    VkDevice _device,
998*61046927SAndroid Build Coastguard Worker    const VkDeviceImageMemoryRequirements *pInfo,
999*61046927SAndroid Build Coastguard Worker    VkMemoryRequirements2 *pMemoryRequirements)
1000*61046927SAndroid Build Coastguard Worker {
1001*61046927SAndroid Build Coastguard Worker    VK_FROM_HANDLE(tu_device, device, _device);
1002*61046927SAndroid Build Coastguard Worker 
1003*61046927SAndroid Build Coastguard Worker    struct tu_image image = {0};
1004*61046927SAndroid Build Coastguard Worker 
1005*61046927SAndroid Build Coastguard Worker    vk_image_init(&device->vk, &image.vk, pInfo->pCreateInfo);
1006*61046927SAndroid Build Coastguard Worker    tu_image_init(device, &image, pInfo->pCreateInfo);
1007*61046927SAndroid Build Coastguard Worker    TU_CALLX(device, tu_image_update_layout)(device, &image, DRM_FORMAT_MOD_INVALID, NULL);
1008*61046927SAndroid Build Coastguard Worker 
1009*61046927SAndroid Build Coastguard Worker    tu_get_image_memory_requirements(device, &image, pMemoryRequirements);
1010*61046927SAndroid Build Coastguard Worker }
1011*61046927SAndroid Build Coastguard Worker 
1012*61046927SAndroid Build Coastguard Worker VKAPI_ATTR void VKAPI_CALL
tu_GetDeviceImageSparseMemoryRequirements(VkDevice device,const VkDeviceImageMemoryRequirements * pInfo,uint32_t * pSparseMemoryRequirementCount,VkSparseImageMemoryRequirements2 * pSparseMemoryRequirements)1013*61046927SAndroid Build Coastguard Worker tu_GetDeviceImageSparseMemoryRequirements(
1014*61046927SAndroid Build Coastguard Worker     VkDevice device,
1015*61046927SAndroid Build Coastguard Worker     const VkDeviceImageMemoryRequirements *pInfo,
1016*61046927SAndroid Build Coastguard Worker     uint32_t *pSparseMemoryRequirementCount,
1017*61046927SAndroid Build Coastguard Worker     VkSparseImageMemoryRequirements2 *pSparseMemoryRequirements)
1018*61046927SAndroid Build Coastguard Worker {
1019*61046927SAndroid Build Coastguard Worker    tu_stub();
1020*61046927SAndroid Build Coastguard Worker }
1021*61046927SAndroid Build Coastguard Worker 
1022*61046927SAndroid Build Coastguard Worker static void
tu_get_image_subresource_layout(struct tu_image * image,const VkImageSubresource2KHR * pSubresource,VkSubresourceLayout2KHR * pLayout)1023*61046927SAndroid Build Coastguard Worker tu_get_image_subresource_layout(struct tu_image *image,
1024*61046927SAndroid Build Coastguard Worker                                 const VkImageSubresource2KHR *pSubresource,
1025*61046927SAndroid Build Coastguard Worker                                 VkSubresourceLayout2KHR *pLayout)
1026*61046927SAndroid Build Coastguard Worker {
1027*61046927SAndroid Build Coastguard Worker    struct fdl_layout *layout =
1028*61046927SAndroid Build Coastguard Worker       &image->layout[tu6_plane_index(image->vk.format,
1029*61046927SAndroid Build Coastguard Worker                                      pSubresource->imageSubresource.aspectMask)];
1030*61046927SAndroid Build Coastguard Worker    const struct fdl_slice *slice = layout->slices +
1031*61046927SAndroid Build Coastguard Worker       pSubresource->imageSubresource.mipLevel;
1032*61046927SAndroid Build Coastguard Worker 
1033*61046927SAndroid Build Coastguard Worker    pLayout->subresourceLayout.offset =
1034*61046927SAndroid Build Coastguard Worker       fdl_surface_offset(layout, pSubresource->imageSubresource.mipLevel,
1035*61046927SAndroid Build Coastguard Worker                          pSubresource->imageSubresource.arrayLayer);
1036*61046927SAndroid Build Coastguard Worker    pLayout->subresourceLayout.rowPitch =
1037*61046927SAndroid Build Coastguard Worker       fdl_pitch(layout, pSubresource->imageSubresource.mipLevel);
1038*61046927SAndroid Build Coastguard Worker    pLayout->subresourceLayout.arrayPitch =
1039*61046927SAndroid Build Coastguard Worker       fdl_layer_stride(layout, pSubresource->imageSubresource.mipLevel);
1040*61046927SAndroid Build Coastguard Worker    pLayout->subresourceLayout.depthPitch = slice->size0;
1041*61046927SAndroid Build Coastguard Worker    pLayout->subresourceLayout.size = slice->size0 * layout->depth0;
1042*61046927SAndroid Build Coastguard Worker 
1043*61046927SAndroid Build Coastguard Worker    if (fdl_ubwc_enabled(layout, pSubresource->imageSubresource.mipLevel)) {
1044*61046927SAndroid Build Coastguard Worker       /* UBWC starts at offset 0 */
1045*61046927SAndroid Build Coastguard Worker       pLayout->subresourceLayout.offset = 0;
1046*61046927SAndroid Build Coastguard Worker       /* UBWC scanout won't match what the kernel wants if we have levels/layers */
1047*61046927SAndroid Build Coastguard Worker       assert(image->vk.mip_levels == 1 && image->vk.array_layers == 1);
1048*61046927SAndroid Build Coastguard Worker    }
1049*61046927SAndroid Build Coastguard Worker }
1050*61046927SAndroid Build Coastguard Worker 
1051*61046927SAndroid Build Coastguard Worker VKAPI_ATTR void VKAPI_CALL
tu_GetImageSubresourceLayout2KHR(VkDevice _device,VkImage _image,const VkImageSubresource2KHR * pSubresource,VkSubresourceLayout2KHR * pLayout)1052*61046927SAndroid Build Coastguard Worker tu_GetImageSubresourceLayout2KHR(VkDevice _device,
1053*61046927SAndroid Build Coastguard Worker                                  VkImage _image,
1054*61046927SAndroid Build Coastguard Worker                                  const VkImageSubresource2KHR *pSubresource,
1055*61046927SAndroid Build Coastguard Worker                                  VkSubresourceLayout2KHR *pLayout)
1056*61046927SAndroid Build Coastguard Worker {
1057*61046927SAndroid Build Coastguard Worker    VK_FROM_HANDLE(tu_image, image, _image);
1058*61046927SAndroid Build Coastguard Worker 
1059*61046927SAndroid Build Coastguard Worker    tu_get_image_subresource_layout(image, pSubresource, pLayout);
1060*61046927SAndroid Build Coastguard Worker }
1061*61046927SAndroid Build Coastguard Worker 
1062*61046927SAndroid Build Coastguard Worker VKAPI_ATTR void VKAPI_CALL
tu_GetDeviceImageSubresourceLayoutKHR(VkDevice _device,const VkDeviceImageSubresourceInfoKHR * pInfo,VkSubresourceLayout2KHR * pLayout)1063*61046927SAndroid Build Coastguard Worker tu_GetDeviceImageSubresourceLayoutKHR(VkDevice _device,
1064*61046927SAndroid Build Coastguard Worker                                       const VkDeviceImageSubresourceInfoKHR *pInfo,
1065*61046927SAndroid Build Coastguard Worker                                       VkSubresourceLayout2KHR *pLayout)
1066*61046927SAndroid Build Coastguard Worker {
1067*61046927SAndroid Build Coastguard Worker    VK_FROM_HANDLE(tu_device, device, _device);
1068*61046927SAndroid Build Coastguard Worker 
1069*61046927SAndroid Build Coastguard Worker    struct tu_image image = {0};
1070*61046927SAndroid Build Coastguard Worker 
1071*61046927SAndroid Build Coastguard Worker    vk_image_init(&device->vk, &image.vk, pInfo->pCreateInfo);
1072*61046927SAndroid Build Coastguard Worker    tu_image_init(device, &image, pInfo->pCreateInfo);
1073*61046927SAndroid Build Coastguard Worker    TU_CALLX(device, tu_image_update_layout)(device, &image, DRM_FORMAT_MOD_INVALID, NULL);
1074*61046927SAndroid Build Coastguard Worker 
1075*61046927SAndroid Build Coastguard Worker    tu_get_image_subresource_layout(&image, pInfo->pSubresource, pLayout);
1076*61046927SAndroid Build Coastguard Worker }
1077*61046927SAndroid Build Coastguard Worker 
1078*61046927SAndroid Build Coastguard Worker VKAPI_ATTR VkResult VKAPI_CALL
tu_CreateImageView(VkDevice _device,const VkImageViewCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkImageView * pView)1079*61046927SAndroid Build Coastguard Worker tu_CreateImageView(VkDevice _device,
1080*61046927SAndroid Build Coastguard Worker                    const VkImageViewCreateInfo *pCreateInfo,
1081*61046927SAndroid Build Coastguard Worker                    const VkAllocationCallbacks *pAllocator,
1082*61046927SAndroid Build Coastguard Worker                    VkImageView *pView)
1083*61046927SAndroid Build Coastguard Worker {
1084*61046927SAndroid Build Coastguard Worker    VK_FROM_HANDLE(tu_device, device, _device);
1085*61046927SAndroid Build Coastguard Worker    struct tu_image_view *view;
1086*61046927SAndroid Build Coastguard Worker 
1087*61046927SAndroid Build Coastguard Worker    view = (struct tu_image_view *) vk_object_alloc(
1088*61046927SAndroid Build Coastguard Worker       &device->vk, pAllocator, sizeof(*view), VK_OBJECT_TYPE_IMAGE_VIEW);
1089*61046927SAndroid Build Coastguard Worker    if (view == NULL)
1090*61046927SAndroid Build Coastguard Worker       return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
1091*61046927SAndroid Build Coastguard Worker 
1092*61046927SAndroid Build Coastguard Worker    tu_image_view_init(device, view, pCreateInfo, device->use_z24uint_s8uint);
1093*61046927SAndroid Build Coastguard Worker 
1094*61046927SAndroid Build Coastguard Worker    *pView = tu_image_view_to_handle(view);
1095*61046927SAndroid Build Coastguard Worker 
1096*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
1097*61046927SAndroid Build Coastguard Worker }
1098*61046927SAndroid Build Coastguard Worker 
1099*61046927SAndroid Build Coastguard Worker VKAPI_ATTR void VKAPI_CALL
tu_DestroyImageView(VkDevice _device,VkImageView _iview,const VkAllocationCallbacks * pAllocator)1100*61046927SAndroid Build Coastguard Worker tu_DestroyImageView(VkDevice _device,
1101*61046927SAndroid Build Coastguard Worker                     VkImageView _iview,
1102*61046927SAndroid Build Coastguard Worker                     const VkAllocationCallbacks *pAllocator)
1103*61046927SAndroid Build Coastguard Worker {
1104*61046927SAndroid Build Coastguard Worker    VK_FROM_HANDLE(tu_device, device, _device);
1105*61046927SAndroid Build Coastguard Worker    VK_FROM_HANDLE(tu_image_view, iview, _iview);
1106*61046927SAndroid Build Coastguard Worker 
1107*61046927SAndroid Build Coastguard Worker    if (!iview)
1108*61046927SAndroid Build Coastguard Worker       return;
1109*61046927SAndroid Build Coastguard Worker 
1110*61046927SAndroid Build Coastguard Worker    vk_object_free(&device->vk, pAllocator, iview);
1111*61046927SAndroid Build Coastguard Worker }
1112*61046927SAndroid Build Coastguard Worker 
1113*61046927SAndroid Build Coastguard Worker /* Impelements the operations described in "Fragment Density Map Operations."
1114*61046927SAndroid Build Coastguard Worker  */
1115*61046927SAndroid Build Coastguard Worker void
tu_fragment_density_map_sample(const struct tu_image_view * fdm,uint32_t x,uint32_t y,uint32_t width,uint32_t height,uint32_t layers,struct tu_frag_area * areas)1116*61046927SAndroid Build Coastguard Worker tu_fragment_density_map_sample(const struct tu_image_view *fdm,
1117*61046927SAndroid Build Coastguard Worker                                uint32_t x, uint32_t y,
1118*61046927SAndroid Build Coastguard Worker                                uint32_t width, uint32_t height,
1119*61046927SAndroid Build Coastguard Worker                                uint32_t layers,
1120*61046927SAndroid Build Coastguard Worker                                struct tu_frag_area *areas)
1121*61046927SAndroid Build Coastguard Worker {
1122*61046927SAndroid Build Coastguard Worker    assert(fdm->image->layout[0].tile_mode == TILE6_LINEAR);
1123*61046927SAndroid Build Coastguard Worker 
1124*61046927SAndroid Build Coastguard Worker    uint32_t fdm_shift_x = util_logbase2_ceil(DIV_ROUND_UP(width, fdm->vk.extent.width));
1125*61046927SAndroid Build Coastguard Worker    uint32_t fdm_shift_y = util_logbase2_ceil(DIV_ROUND_UP(height, fdm->vk.extent.height));
1126*61046927SAndroid Build Coastguard Worker 
1127*61046927SAndroid Build Coastguard Worker    fdm_shift_x = CLAMP(fdm_shift_x, MIN_FDM_TEXEL_SIZE_LOG2, MAX_FDM_TEXEL_SIZE_LOG2);
1128*61046927SAndroid Build Coastguard Worker    fdm_shift_y = CLAMP(fdm_shift_y, MIN_FDM_TEXEL_SIZE_LOG2, MAX_FDM_TEXEL_SIZE_LOG2);
1129*61046927SAndroid Build Coastguard Worker 
1130*61046927SAndroid Build Coastguard Worker    uint32_t i = x >> fdm_shift_x;
1131*61046927SAndroid Build Coastguard Worker    uint32_t j = y >> fdm_shift_y;
1132*61046927SAndroid Build Coastguard Worker 
1133*61046927SAndroid Build Coastguard Worker    unsigned cpp = fdm->image->layout[0].cpp;
1134*61046927SAndroid Build Coastguard Worker    unsigned pitch = fdm->view.pitch;
1135*61046927SAndroid Build Coastguard Worker 
1136*61046927SAndroid Build Coastguard Worker    void *pixel = (char *)fdm->image->map + fdm->view.offset + cpp * i + pitch * j;
1137*61046927SAndroid Build Coastguard Worker    for (unsigned i = 0; i < layers; i++) {
1138*61046927SAndroid Build Coastguard Worker       float density_src[4], density[4];
1139*61046927SAndroid Build Coastguard Worker       util_format_unpack_rgba(fdm->view.format, density_src, pixel, 1);
1140*61046927SAndroid Build Coastguard Worker       pipe_swizzle_4f(density, density_src, fdm->swizzle);
1141*61046927SAndroid Build Coastguard Worker       areas[i].width = 1.0f / density[0];
1142*61046927SAndroid Build Coastguard Worker       areas[i].height = 1.0f / density[1];
1143*61046927SAndroid Build Coastguard Worker 
1144*61046927SAndroid Build Coastguard Worker       pixel = (char *)pixel + fdm->view.layer_size;
1145*61046927SAndroid Build Coastguard Worker    }
1146*61046927SAndroid Build Coastguard Worker }
1147