xref: /aosp_15_r20/external/mesa3d/src/asahi/vulkan/hk_sampler.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker  * Copyright 2024 Valve Corporation
3*61046927SAndroid Build Coastguard Worker  * Copyright 2024 Alyssa Rosenzweig
4*61046927SAndroid Build Coastguard Worker  * Copyright 2022-2023 Collabora Ltd. and Red Hat Inc.
5*61046927SAndroid Build Coastguard Worker  * SPDX-License-Identifier: MIT
6*61046927SAndroid Build Coastguard Worker  */
7*61046927SAndroid Build Coastguard Worker #include "hk_sampler.h"
8*61046927SAndroid Build Coastguard Worker 
9*61046927SAndroid Build Coastguard Worker #include "hk_device.h"
10*61046927SAndroid Build Coastguard Worker #include "hk_entrypoints.h"
11*61046927SAndroid Build Coastguard Worker #include "hk_physical_device.h"
12*61046927SAndroid Build Coastguard Worker 
13*61046927SAndroid Build Coastguard Worker #include "vk_enum_to_str.h"
14*61046927SAndroid Build Coastguard Worker #include "vk_format.h"
15*61046927SAndroid Build Coastguard Worker #include "vk_sampler.h"
16*61046927SAndroid Build Coastguard Worker 
17*61046927SAndroid Build Coastguard Worker #include "asahi/genxml/agx_pack.h"
18*61046927SAndroid Build Coastguard Worker 
19*61046927SAndroid Build Coastguard Worker static inline uint32_t
translate_address_mode(VkSamplerAddressMode addr_mode)20*61046927SAndroid Build Coastguard Worker translate_address_mode(VkSamplerAddressMode addr_mode)
21*61046927SAndroid Build Coastguard Worker {
22*61046927SAndroid Build Coastguard Worker #define MODE(VK, AGX_) [VK_SAMPLER_ADDRESS_MODE_##VK] = AGX_WRAP_##AGX_
23*61046927SAndroid Build Coastguard Worker    static const uint8_t translate[] = {
24*61046927SAndroid Build Coastguard Worker       MODE(REPEAT, REPEAT),
25*61046927SAndroid Build Coastguard Worker       MODE(MIRRORED_REPEAT, MIRRORED_REPEAT),
26*61046927SAndroid Build Coastguard Worker       MODE(CLAMP_TO_EDGE, CLAMP_TO_EDGE),
27*61046927SAndroid Build Coastguard Worker       MODE(CLAMP_TO_BORDER, CLAMP_TO_BORDER),
28*61046927SAndroid Build Coastguard Worker       MODE(MIRROR_CLAMP_TO_EDGE, MIRRORED_CLAMP_TO_EDGE),
29*61046927SAndroid Build Coastguard Worker    };
30*61046927SAndroid Build Coastguard Worker #undef MODE
31*61046927SAndroid Build Coastguard Worker 
32*61046927SAndroid Build Coastguard Worker    assert(addr_mode < ARRAY_SIZE(translate));
33*61046927SAndroid Build Coastguard Worker    return translate[addr_mode];
34*61046927SAndroid Build Coastguard Worker }
35*61046927SAndroid Build Coastguard Worker 
36*61046927SAndroid Build Coastguard Worker static uint32_t
translate_texsamp_compare_op(VkCompareOp op)37*61046927SAndroid Build Coastguard Worker translate_texsamp_compare_op(VkCompareOp op)
38*61046927SAndroid Build Coastguard Worker {
39*61046927SAndroid Build Coastguard Worker #define OP(VK, AGX_) [VK_COMPARE_OP_##VK] = AGX_COMPARE_FUNC_##AGX_
40*61046927SAndroid Build Coastguard Worker    static const uint8_t translate[] = {
41*61046927SAndroid Build Coastguard Worker       OP(NEVER, NEVER),
42*61046927SAndroid Build Coastguard Worker       OP(LESS, LESS),
43*61046927SAndroid Build Coastguard Worker       OP(EQUAL, EQUAL),
44*61046927SAndroid Build Coastguard Worker       OP(LESS_OR_EQUAL, LEQUAL),
45*61046927SAndroid Build Coastguard Worker       OP(GREATER, GREATER),
46*61046927SAndroid Build Coastguard Worker       OP(NOT_EQUAL, NOT_EQUAL),
47*61046927SAndroid Build Coastguard Worker       OP(GREATER_OR_EQUAL, GEQUAL),
48*61046927SAndroid Build Coastguard Worker       OP(ALWAYS, ALWAYS),
49*61046927SAndroid Build Coastguard Worker    };
50*61046927SAndroid Build Coastguard Worker #undef OP
51*61046927SAndroid Build Coastguard Worker 
52*61046927SAndroid Build Coastguard Worker    assert(op < ARRAY_SIZE(translate));
53*61046927SAndroid Build Coastguard Worker    return translate[op];
54*61046927SAndroid Build Coastguard Worker }
55*61046927SAndroid Build Coastguard Worker 
56*61046927SAndroid Build Coastguard Worker static enum agx_filter
translate_filter(VkFilter filter)57*61046927SAndroid Build Coastguard Worker translate_filter(VkFilter filter)
58*61046927SAndroid Build Coastguard Worker {
59*61046927SAndroid Build Coastguard Worker    static_assert((enum agx_filter)VK_FILTER_NEAREST == AGX_FILTER_NEAREST);
60*61046927SAndroid Build Coastguard Worker    static_assert((enum agx_filter)VK_FILTER_LINEAR == AGX_FILTER_LINEAR);
61*61046927SAndroid Build Coastguard Worker 
62*61046927SAndroid Build Coastguard Worker    return (enum agx_filter)filter;
63*61046927SAndroid Build Coastguard Worker }
64*61046927SAndroid Build Coastguard Worker 
65*61046927SAndroid Build Coastguard Worker static enum agx_mip_filter
translate_mipfilter(VkSamplerMipmapMode mode)66*61046927SAndroid Build Coastguard Worker translate_mipfilter(VkSamplerMipmapMode mode)
67*61046927SAndroid Build Coastguard Worker {
68*61046927SAndroid Build Coastguard Worker    switch (mode) {
69*61046927SAndroid Build Coastguard Worker    case VK_SAMPLER_MIPMAP_MODE_NEAREST:
70*61046927SAndroid Build Coastguard Worker       return AGX_MIP_FILTER_NEAREST;
71*61046927SAndroid Build Coastguard Worker 
72*61046927SAndroid Build Coastguard Worker    case VK_SAMPLER_MIPMAP_MODE_LINEAR:
73*61046927SAndroid Build Coastguard Worker       return AGX_MIP_FILTER_LINEAR;
74*61046927SAndroid Build Coastguard Worker 
75*61046927SAndroid Build Coastguard Worker    default:
76*61046927SAndroid Build Coastguard Worker       unreachable("Invalid filter");
77*61046927SAndroid Build Coastguard Worker    }
78*61046927SAndroid Build Coastguard Worker }
79*61046927SAndroid Build Coastguard Worker 
80*61046927SAndroid Build Coastguard Worker static bool
uses_border(const VkSamplerCreateInfo * info)81*61046927SAndroid Build Coastguard Worker uses_border(const VkSamplerCreateInfo *info)
82*61046927SAndroid Build Coastguard Worker {
83*61046927SAndroid Build Coastguard Worker    return info->addressModeU == VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER ||
84*61046927SAndroid Build Coastguard Worker           info->addressModeV == VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER ||
85*61046927SAndroid Build Coastguard Worker           info->addressModeW == VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER;
86*61046927SAndroid Build Coastguard Worker }
87*61046927SAndroid Build Coastguard Worker 
88*61046927SAndroid Build Coastguard Worker static enum agx_border_colour
is_border_color_custom(VkBorderColor color)89*61046927SAndroid Build Coastguard Worker is_border_color_custom(VkBorderColor color)
90*61046927SAndroid Build Coastguard Worker {
91*61046927SAndroid Build Coastguard Worker    /* TODO: for now, opaque black is treated as custom due to rgba4 swizzling
92*61046927SAndroid Build Coastguard Worker     * issues, could be optimized though.
93*61046927SAndroid Build Coastguard Worker     */
94*61046927SAndroid Build Coastguard Worker    switch (color) {
95*61046927SAndroid Build Coastguard Worker    case VK_BORDER_COLOR_INT_OPAQUE_BLACK:
96*61046927SAndroid Build Coastguard Worker    case VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK:
97*61046927SAndroid Build Coastguard Worker    case VK_BORDER_COLOR_INT_CUSTOM_EXT:
98*61046927SAndroid Build Coastguard Worker    case VK_BORDER_COLOR_FLOAT_CUSTOM_EXT:
99*61046927SAndroid Build Coastguard Worker       return true;
100*61046927SAndroid Build Coastguard Worker    default:
101*61046927SAndroid Build Coastguard Worker       return false;
102*61046927SAndroid Build Coastguard Worker    }
103*61046927SAndroid Build Coastguard Worker }
104*61046927SAndroid Build Coastguard Worker 
105*61046927SAndroid Build Coastguard Worker /* Translate an American VkBorderColor into a Canadian agx_border_colour */
106*61046927SAndroid Build Coastguard Worker static enum agx_border_colour
translate_border_color(VkBorderColor color,bool custom_to_1)107*61046927SAndroid Build Coastguard Worker translate_border_color(VkBorderColor color, bool custom_to_1)
108*61046927SAndroid Build Coastguard Worker {
109*61046927SAndroid Build Coastguard Worker    switch (color) {
110*61046927SAndroid Build Coastguard Worker    case VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK:
111*61046927SAndroid Build Coastguard Worker    case VK_BORDER_COLOR_INT_TRANSPARENT_BLACK:
112*61046927SAndroid Build Coastguard Worker       return AGX_BORDER_COLOUR_TRANSPARENT_BLACK;
113*61046927SAndroid Build Coastguard Worker 
114*61046927SAndroid Build Coastguard Worker    case VK_BORDER_COLOR_INT_OPAQUE_WHITE:
115*61046927SAndroid Build Coastguard Worker    case VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE:
116*61046927SAndroid Build Coastguard Worker       return AGX_BORDER_COLOUR_OPAQUE_WHITE;
117*61046927SAndroid Build Coastguard Worker 
118*61046927SAndroid Build Coastguard Worker    default:
119*61046927SAndroid Build Coastguard Worker       assert(is_border_color_custom(color));
120*61046927SAndroid Build Coastguard Worker       return custom_to_1 ? AGX_BORDER_COLOUR_OPAQUE_WHITE
121*61046927SAndroid Build Coastguard Worker                          : AGX_BORDER_COLOUR_TRANSPARENT_BLACK;
122*61046927SAndroid Build Coastguard Worker    }
123*61046927SAndroid Build Coastguard Worker }
124*61046927SAndroid Build Coastguard Worker 
125*61046927SAndroid Build Coastguard Worker static void
pack_sampler(const struct hk_physical_device * pdev,const struct VkSamplerCreateInfo * info,bool custom_to_1,struct agx_sampler_packed * out)126*61046927SAndroid Build Coastguard Worker pack_sampler(const struct hk_physical_device *pdev,
127*61046927SAndroid Build Coastguard Worker              const struct VkSamplerCreateInfo *info, bool custom_to_1,
128*61046927SAndroid Build Coastguard Worker              struct agx_sampler_packed *out)
129*61046927SAndroid Build Coastguard Worker {
130*61046927SAndroid Build Coastguard Worker    agx_pack(out, SAMPLER, cfg) {
131*61046927SAndroid Build Coastguard Worker       cfg.minimum_lod = info->minLod;
132*61046927SAndroid Build Coastguard Worker       cfg.maximum_lod = info->maxLod;
133*61046927SAndroid Build Coastguard Worker       cfg.magnify = translate_filter(info->magFilter);
134*61046927SAndroid Build Coastguard Worker       cfg.minify = translate_filter(info->minFilter);
135*61046927SAndroid Build Coastguard Worker       cfg.mip_filter = translate_mipfilter(info->mipmapMode);
136*61046927SAndroid Build Coastguard Worker       cfg.wrap_s = translate_address_mode(info->addressModeU);
137*61046927SAndroid Build Coastguard Worker       cfg.wrap_t = translate_address_mode(info->addressModeV);
138*61046927SAndroid Build Coastguard Worker       cfg.wrap_r = translate_address_mode(info->addressModeW);
139*61046927SAndroid Build Coastguard Worker       cfg.pixel_coordinates = info->unnormalizedCoordinates;
140*61046927SAndroid Build Coastguard Worker 
141*61046927SAndroid Build Coastguard Worker       cfg.seamful_cube_maps =
142*61046927SAndroid Build Coastguard Worker          info->flags & VK_SAMPLER_CREATE_NON_SEAMLESS_CUBE_MAP_BIT_EXT;
143*61046927SAndroid Build Coastguard Worker 
144*61046927SAndroid Build Coastguard Worker       if (info->compareEnable) {
145*61046927SAndroid Build Coastguard Worker          cfg.compare_func = translate_texsamp_compare_op(info->compareOp);
146*61046927SAndroid Build Coastguard Worker          cfg.compare_enable = true;
147*61046927SAndroid Build Coastguard Worker       }
148*61046927SAndroid Build Coastguard Worker 
149*61046927SAndroid Build Coastguard Worker       if (info->anisotropyEnable) {
150*61046927SAndroid Build Coastguard Worker          cfg.maximum_anisotropy =
151*61046927SAndroid Build Coastguard Worker             util_next_power_of_two(MAX2(info->maxAnisotropy, 1));
152*61046927SAndroid Build Coastguard Worker       } else {
153*61046927SAndroid Build Coastguard Worker          cfg.maximum_anisotropy = 1;
154*61046927SAndroid Build Coastguard Worker       }
155*61046927SAndroid Build Coastguard Worker 
156*61046927SAndroid Build Coastguard Worker       if (uses_border(info)) {
157*61046927SAndroid Build Coastguard Worker          cfg.border_colour =
158*61046927SAndroid Build Coastguard Worker             translate_border_color(info->borderColor, custom_to_1);
159*61046927SAndroid Build Coastguard Worker       }
160*61046927SAndroid Build Coastguard Worker    }
161*61046927SAndroid Build Coastguard Worker }
162*61046927SAndroid Build Coastguard Worker 
163*61046927SAndroid Build Coastguard Worker VKAPI_ATTR VkResult VKAPI_CALL
hk_CreateSampler(VkDevice device,const VkSamplerCreateInfo * info,const VkAllocationCallbacks * pAllocator,VkSampler * pSampler)164*61046927SAndroid Build Coastguard Worker hk_CreateSampler(VkDevice device,
165*61046927SAndroid Build Coastguard Worker                  const VkSamplerCreateInfo *info /* pCreateInfo */,
166*61046927SAndroid Build Coastguard Worker                  const VkAllocationCallbacks *pAllocator, VkSampler *pSampler)
167*61046927SAndroid Build Coastguard Worker {
168*61046927SAndroid Build Coastguard Worker    VK_FROM_HANDLE(hk_device, dev, device);
169*61046927SAndroid Build Coastguard Worker    struct hk_physical_device *pdev = hk_device_physical(dev);
170*61046927SAndroid Build Coastguard Worker    struct hk_sampler *sampler;
171*61046927SAndroid Build Coastguard Worker    VkResult result;
172*61046927SAndroid Build Coastguard Worker 
173*61046927SAndroid Build Coastguard Worker    sampler = vk_sampler_create(&dev->vk, info, pAllocator, sizeof(*sampler));
174*61046927SAndroid Build Coastguard Worker    if (!sampler)
175*61046927SAndroid Build Coastguard Worker       return vk_error(dev, VK_ERROR_OUT_OF_HOST_MEMORY);
176*61046927SAndroid Build Coastguard Worker 
177*61046927SAndroid Build Coastguard Worker    struct agx_sampler_packed samp;
178*61046927SAndroid Build Coastguard Worker    pack_sampler(pdev, info, true, &samp);
179*61046927SAndroid Build Coastguard Worker 
180*61046927SAndroid Build Coastguard Worker    /* LOD bias passed in the descriptor set */
181*61046927SAndroid Build Coastguard Worker    sampler->lod_bias_fp16 = _mesa_float_to_half(info->mipLodBias);
182*61046927SAndroid Build Coastguard Worker 
183*61046927SAndroid Build Coastguard Worker    result =
184*61046927SAndroid Build Coastguard Worker       hk_sampler_heap_add(dev, samp, &sampler->planes[sampler->plane_count].hw);
185*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS) {
186*61046927SAndroid Build Coastguard Worker       hk_DestroySampler(device, hk_sampler_to_handle(sampler), pAllocator);
187*61046927SAndroid Build Coastguard Worker       return result;
188*61046927SAndroid Build Coastguard Worker    }
189*61046927SAndroid Build Coastguard Worker 
190*61046927SAndroid Build Coastguard Worker    sampler->plane_count++;
191*61046927SAndroid Build Coastguard Worker 
192*61046927SAndroid Build Coastguard Worker    /* In order to support CONVERSION_SEPARATE_RECONSTRUCTION_FILTER_BIT, we
193*61046927SAndroid Build Coastguard Worker     * need multiple sampler planes: at minimum we will need one for luminance
194*61046927SAndroid Build Coastguard Worker     * (the default), and one for chroma.  Each sampler plane needs its own
195*61046927SAndroid Build Coastguard Worker     * sampler table entry.  However, sampler table entries are very rare on
196*61046927SAndroid Build Coastguard Worker     * G13, and each plane would burn one of those. So we make sure to allocate
197*61046927SAndroid Build Coastguard Worker     * only the minimum amount that we actually need (i.e., either 1 or 2), and
198*61046927SAndroid Build Coastguard Worker     * then just copy the last sampler plane out as far as we need to fill the
199*61046927SAndroid Build Coastguard Worker     * number of image planes.
200*61046927SAndroid Build Coastguard Worker     */
201*61046927SAndroid Build Coastguard Worker    if (sampler->vk.ycbcr_conversion) {
202*61046927SAndroid Build Coastguard Worker       assert(!uses_border(info) &&
203*61046927SAndroid Build Coastguard Worker              "consequence of VUID-VkSamplerCreateInfo-addressModeU-01646");
204*61046927SAndroid Build Coastguard Worker 
205*61046927SAndroid Build Coastguard Worker       const VkFilter chroma_filter =
206*61046927SAndroid Build Coastguard Worker          sampler->vk.ycbcr_conversion->state.chroma_filter;
207*61046927SAndroid Build Coastguard Worker       if (info->magFilter != chroma_filter ||
208*61046927SAndroid Build Coastguard Worker           info->minFilter != chroma_filter) {
209*61046927SAndroid Build Coastguard Worker          VkSamplerCreateInfo plane2_info = *info;
210*61046927SAndroid Build Coastguard Worker          plane2_info.magFilter = chroma_filter;
211*61046927SAndroid Build Coastguard Worker          plane2_info.minFilter = chroma_filter;
212*61046927SAndroid Build Coastguard Worker 
213*61046927SAndroid Build Coastguard Worker          pack_sampler(pdev, &plane2_info, false, &samp);
214*61046927SAndroid Build Coastguard Worker          result = hk_sampler_heap_add(
215*61046927SAndroid Build Coastguard Worker             dev, samp, &sampler->planes[sampler->plane_count].hw);
216*61046927SAndroid Build Coastguard Worker 
217*61046927SAndroid Build Coastguard Worker          if (result != VK_SUCCESS) {
218*61046927SAndroid Build Coastguard Worker             hk_DestroySampler(device, hk_sampler_to_handle(sampler),
219*61046927SAndroid Build Coastguard Worker                               pAllocator);
220*61046927SAndroid Build Coastguard Worker             return result;
221*61046927SAndroid Build Coastguard Worker          }
222*61046927SAndroid Build Coastguard Worker 
223*61046927SAndroid Build Coastguard Worker          sampler->plane_count++;
224*61046927SAndroid Build Coastguard Worker       }
225*61046927SAndroid Build Coastguard Worker    } else if (uses_border(info)) {
226*61046927SAndroid Build Coastguard Worker       /* If the sampler uses custom border colours, we need both clamp-to-1
227*61046927SAndroid Build Coastguard Worker        * and clamp-to-0 variants. We treat these as planes.
228*61046927SAndroid Build Coastguard Worker        */
229*61046927SAndroid Build Coastguard Worker       pack_sampler(pdev, info, false, &samp);
230*61046927SAndroid Build Coastguard Worker       result = hk_sampler_heap_add(dev, samp,
231*61046927SAndroid Build Coastguard Worker                                    &sampler->planes[sampler->plane_count].hw);
232*61046927SAndroid Build Coastguard Worker 
233*61046927SAndroid Build Coastguard Worker       if (result != VK_SUCCESS) {
234*61046927SAndroid Build Coastguard Worker          hk_DestroySampler(device, hk_sampler_to_handle(sampler), pAllocator);
235*61046927SAndroid Build Coastguard Worker          return result;
236*61046927SAndroid Build Coastguard Worker       }
237*61046927SAndroid Build Coastguard Worker 
238*61046927SAndroid Build Coastguard Worker       sampler->plane_count++;
239*61046927SAndroid Build Coastguard Worker 
240*61046927SAndroid Build Coastguard Worker       /* We also need to record the border.
241*61046927SAndroid Build Coastguard Worker        *
242*61046927SAndroid Build Coastguard Worker        * If there is a border colour component mapping, we need to swizzle with
243*61046927SAndroid Build Coastguard Worker        * it. Otherwise, we can assume there's nothing to do.
244*61046927SAndroid Build Coastguard Worker        */
245*61046927SAndroid Build Coastguard Worker       VkClearColorValue bc = sampler->vk.border_color_value;
246*61046927SAndroid Build Coastguard Worker 
247*61046927SAndroid Build Coastguard Worker       const VkSamplerBorderColorComponentMappingCreateInfoEXT *swiz_info =
248*61046927SAndroid Build Coastguard Worker          vk_find_struct_const(
249*61046927SAndroid Build Coastguard Worker             info->pNext,
250*61046927SAndroid Build Coastguard Worker             SAMPLER_BORDER_COLOR_COMPONENT_MAPPING_CREATE_INFO_EXT);
251*61046927SAndroid Build Coastguard Worker 
252*61046927SAndroid Build Coastguard Worker       if (swiz_info) {
253*61046927SAndroid Build Coastguard Worker          const bool is_int = vk_border_color_is_int(info->borderColor);
254*61046927SAndroid Build Coastguard Worker          bc = vk_swizzle_color_value(bc, swiz_info->components, is_int);
255*61046927SAndroid Build Coastguard Worker       }
256*61046927SAndroid Build Coastguard Worker 
257*61046927SAndroid Build Coastguard Worker       sampler->custom_border = bc;
258*61046927SAndroid Build Coastguard Worker       sampler->has_border = true;
259*61046927SAndroid Build Coastguard Worker    }
260*61046927SAndroid Build Coastguard Worker 
261*61046927SAndroid Build Coastguard Worker    *pSampler = hk_sampler_to_handle(sampler);
262*61046927SAndroid Build Coastguard Worker 
263*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
264*61046927SAndroid Build Coastguard Worker }
265*61046927SAndroid Build Coastguard Worker 
266*61046927SAndroid Build Coastguard Worker VKAPI_ATTR void VKAPI_CALL
hk_DestroySampler(VkDevice device,VkSampler _sampler,const VkAllocationCallbacks * pAllocator)267*61046927SAndroid Build Coastguard Worker hk_DestroySampler(VkDevice device, VkSampler _sampler,
268*61046927SAndroid Build Coastguard Worker                   const VkAllocationCallbacks *pAllocator)
269*61046927SAndroid Build Coastguard Worker {
270*61046927SAndroid Build Coastguard Worker    VK_FROM_HANDLE(hk_device, dev, device);
271*61046927SAndroid Build Coastguard Worker    VK_FROM_HANDLE(hk_sampler, sampler, _sampler);
272*61046927SAndroid Build Coastguard Worker 
273*61046927SAndroid Build Coastguard Worker    if (!sampler)
274*61046927SAndroid Build Coastguard Worker       return;
275*61046927SAndroid Build Coastguard Worker 
276*61046927SAndroid Build Coastguard Worker    for (uint8_t plane = 0; plane < sampler->plane_count; plane++) {
277*61046927SAndroid Build Coastguard Worker       hk_sampler_heap_remove(dev, sampler->planes[plane].hw);
278*61046927SAndroid Build Coastguard Worker    }
279*61046927SAndroid Build Coastguard Worker 
280*61046927SAndroid Build Coastguard Worker    vk_sampler_destroy(&dev->vk, pAllocator, &sampler->vk);
281*61046927SAndroid Build Coastguard Worker }
282