~mmach/netext73/mesa-haswell

« back to all changes in this revision

Viewing changes to src/amd/vulkan/radv_image.c

  • Committer: mmach
  • Date: 2022-09-22 19:56:13 UTC
  • Revision ID: netbit73@gmail.com-20220922195613-wtik9mmy20tmor0i
2022-09-22 21:17:09

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Copyright © 2016 Red Hat.
3
 
 * Copyright © 2016 Bas Nieuwenhuizen
4
 
 *
5
 
 * based in part on anv driver which is:
6
 
 * Copyright © 2015 Intel Corporation
7
 
 *
8
 
 * Permission is hereby granted, free of charge, to any person obtaining a
9
 
 * copy of this software and associated documentation files (the "Software"),
10
 
 * to deal in the Software without restriction, including without limitation
11
 
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12
 
 * and/or sell copies of the Software, and to permit persons to whom the
13
 
 * Software is furnished to do so, subject to the following conditions:
14
 
 *
15
 
 * The above copyright notice and this permission notice (including the next
16
 
 * paragraph) shall be included in all copies or substantial portions of the
17
 
 * Software.
18
 
 *
19
 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
 
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
 
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
22
 
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
 
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24
 
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
25
 
 * IN THE SOFTWARE.
26
 
 */
27
 
 
28
 
#include "ac_drm_fourcc.h"
29
 
#include "util/debug.h"
30
 
#include "util/u_atomic.h"
31
 
#include "vulkan/util/vk_format.h"
32
 
#include "radv_debug.h"
33
 
#include "radv_private.h"
34
 
#include "radv_radeon_winsys.h"
35
 
#include "sid.h"
36
 
#include "vk_format.h"
37
 
#include "vk_util.h"
38
 
 
39
 
#include "gfx10_format_table.h"
40
 
 
41
 
static const VkImageUsageFlagBits RADV_IMAGE_USAGE_WRITE_BITS =
42
 
   VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
43
 
   VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_STORAGE_BIT;
44
 
 
45
 
static unsigned
46
 
radv_choose_tiling(struct radv_device *device, const VkImageCreateInfo *pCreateInfo,
47
 
                   VkFormat format)
48
 
{
49
 
   if (pCreateInfo->tiling == VK_IMAGE_TILING_LINEAR) {
50
 
      assert(pCreateInfo->samples <= 1);
51
 
      return RADEON_SURF_MODE_LINEAR_ALIGNED;
52
 
   }
53
 
 
54
 
   /* MSAA resources must be 2D tiled. */
55
 
   if (pCreateInfo->samples > 1)
56
 
      return RADEON_SURF_MODE_2D;
57
 
 
58
 
   if (!vk_format_is_compressed(format) && !vk_format_is_depth_or_stencil(format) &&
59
 
       device->physical_device->rad_info.chip_class <= GFX8) {
60
 
      /* this causes hangs in some VK CTS tests on GFX9. */
61
 
      /* Textures with a very small height are recommended to be linear. */
62
 
      if (pCreateInfo->imageType == VK_IMAGE_TYPE_1D ||
63
 
          /* Only very thin and long 2D textures should benefit from
64
 
           * linear_aligned. */
65
 
          (pCreateInfo->extent.width > 8 && pCreateInfo->extent.height <= 2))
66
 
         return RADEON_SURF_MODE_LINEAR_ALIGNED;
67
 
   }
68
 
 
69
 
   return RADEON_SURF_MODE_2D;
70
 
}
71
 
 
72
 
static bool
73
 
radv_use_tc_compat_htile_for_image(struct radv_device *device, const VkImageCreateInfo *pCreateInfo,
74
 
                                   VkFormat format)
75
 
{
76
 
   /* TC-compat HTILE is only available for GFX8+. */
77
 
   if (device->physical_device->rad_info.chip_class < GFX8)
78
 
      return false;
79
 
 
80
 
   if ((pCreateInfo->usage & VK_IMAGE_USAGE_STORAGE_BIT))
81
 
      return false;
82
 
 
83
 
   if (pCreateInfo->tiling == VK_IMAGE_TILING_LINEAR)
84
 
      return false;
85
 
 
86
 
   /* Do not enable TC-compatible HTILE if the image isn't readable by a
87
 
    * shader because no texture fetches will happen.
88
 
    */
89
 
   if (!(pCreateInfo->usage & (VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT |
90
 
                               VK_IMAGE_USAGE_TRANSFER_SRC_BIT)))
91
 
      return false;
92
 
 
93
 
   if (device->physical_device->rad_info.chip_class < GFX9) {
94
 
      /* TC-compat HTILE for MSAA depth/stencil images is broken
95
 
       * on GFX8 because the tiling doesn't match.
96
 
       */
97
 
      if (pCreateInfo->samples >= 2 && format == VK_FORMAT_D32_SFLOAT_S8_UINT)
98
 
         return false;
99
 
 
100
 
      /* GFX9+ supports compression for both 32-bit and 16-bit depth
101
 
       * surfaces, while GFX8 only supports 32-bit natively. Though,
102
 
       * the driver allows TC-compat HTILE for 16-bit depth surfaces
103
 
       * with no Z planes compression.
104
 
       */
105
 
      if (format != VK_FORMAT_D32_SFLOAT_S8_UINT && format != VK_FORMAT_D32_SFLOAT &&
106
 
          format != VK_FORMAT_D16_UNORM)
107
 
         return false;
108
 
   }
109
 
 
110
 
   return true;
111
 
}
112
 
 
113
 
static bool
114
 
radv_surface_has_scanout(struct radv_device *device, const struct radv_image_create_info *info)
115
 
{
116
 
   if (info->bo_metadata) {
117
 
      if (device->physical_device->rad_info.chip_class >= GFX9)
118
 
         return info->bo_metadata->u.gfx9.scanout;
119
 
      else
120
 
         return info->bo_metadata->u.legacy.scanout;
121
 
   }
122
 
 
123
 
   return info->scanout;
124
 
}
125
 
 
126
 
static bool
127
 
radv_image_use_fast_clear_for_image_early(const struct radv_device *device,
128
 
                                          const struct radv_image *image)
129
 
{
130
 
   if (device->instance->debug_flags & RADV_DEBUG_FORCE_COMPRESS)
131
 
      return true;
132
 
 
133
 
   if (image->info.samples <= 1 && image->info.width * image->info.height <= 512 * 512) {
134
 
      /* Do not enable CMASK or DCC for small surfaces where the cost
135
 
       * of the eliminate pass can be higher than the benefit of fast
136
 
       * clear. RadeonSI does this, but the image threshold is
137
 
       * different.
138
 
       */
139
 
      return false;
140
 
   }
141
 
 
142
 
   return !!(image->usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
143
 
}
144
 
 
145
 
static bool
146
 
radv_image_use_fast_clear_for_image(const struct radv_device *device,
147
 
                                    const struct radv_image *image)
148
 
{
149
 
   if (device->instance->debug_flags & RADV_DEBUG_FORCE_COMPRESS)
150
 
      return true;
151
 
 
152
 
   return radv_image_use_fast_clear_for_image_early(device, image) &&
153
 
          (image->exclusive ||
154
 
           /* Enable DCC for concurrent images if stores are
155
 
            * supported because that means we can keep DCC compressed on
156
 
            * all layouts/queues.
157
 
            */
158
 
           radv_image_use_dcc_image_stores(device, image));
159
 
}
160
 
 
161
 
bool
162
 
radv_are_formats_dcc_compatible(const struct radv_physical_device *pdev, const void *pNext,
163
 
                                VkFormat format, VkImageCreateFlags flags, bool *sign_reinterpret)
164
 
{
165
 
   bool blendable;
166
 
 
167
 
   if (!radv_is_colorbuffer_format_supported(pdev, format, &blendable))
168
 
      return false;
169
 
 
170
 
   if (sign_reinterpret != NULL)
171
 
      *sign_reinterpret = false;
172
 
 
173
 
   if (flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT) {
174
 
      const struct VkImageFormatListCreateInfo *format_list =
175
 
         (const struct VkImageFormatListCreateInfo *)vk_find_struct_const(
176
 
            pNext, IMAGE_FORMAT_LIST_CREATE_INFO);
177
 
 
178
 
      /* We have to ignore the existence of the list if viewFormatCount = 0 */
179
 
      if (format_list && format_list->viewFormatCount) {
180
 
         /* compatibility is transitive, so we only need to check
181
 
          * one format with everything else. */
182
 
         for (unsigned i = 0; i < format_list->viewFormatCount; ++i) {
183
 
            if (format_list->pViewFormats[i] == VK_FORMAT_UNDEFINED)
184
 
               continue;
185
 
 
186
 
            if (!radv_dcc_formats_compatible(format, format_list->pViewFormats[i],
187
 
                                             sign_reinterpret))
188
 
               return false;
189
 
         }
190
 
      } else {
191
 
         return false;
192
 
      }
193
 
   }
194
 
 
195
 
   return true;
196
 
}
197
 
 
198
 
static bool
199
 
radv_format_is_atomic_allowed(struct radv_device *device, VkFormat format)
200
 
{
201
 
   if (format == VK_FORMAT_R32_SFLOAT && !device->image_float32_atomics)
202
 
      return false;
203
 
 
204
 
   return radv_is_atomic_format_supported(format);
205
 
}
206
 
 
207
 
static bool
208
 
radv_formats_is_atomic_allowed(struct radv_device *device, const void *pNext, VkFormat format,
209
 
                               VkImageCreateFlags flags)
210
 
{
211
 
   if (radv_format_is_atomic_allowed(device, format))
212
 
      return true;
213
 
 
214
 
   if (flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT) {
215
 
      const struct VkImageFormatListCreateInfo *format_list =
216
 
         (const struct VkImageFormatListCreateInfo *)vk_find_struct_const(
217
 
            pNext, IMAGE_FORMAT_LIST_CREATE_INFO);
218
 
 
219
 
      /* We have to ignore the existence of the list if viewFormatCount = 0 */
220
 
      if (format_list && format_list->viewFormatCount) {
221
 
         for (unsigned i = 0; i < format_list->viewFormatCount; ++i) {
222
 
            if (radv_format_is_atomic_allowed(device, format_list->pViewFormats[i]))
223
 
               return true;
224
 
         }
225
 
      }
226
 
   }
227
 
 
228
 
   return false;
229
 
}
230
 
 
231
 
static bool
232
 
radv_use_dcc_for_image_early(struct radv_device *device, struct radv_image *image,
233
 
                             const VkImageCreateInfo *pCreateInfo, VkFormat format,
234
 
                             bool *sign_reinterpret)
235
 
{
236
 
   /* DCC (Delta Color Compression) is only available for GFX8+. */
237
 
   if (device->physical_device->rad_info.chip_class < GFX8)
238
 
      return false;
239
 
 
240
 
   if (device->instance->debug_flags & RADV_DEBUG_NO_DCC)
241
 
      return false;
242
 
 
243
 
   if (image->shareable && image->tiling != VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT)
244
 
      return false;
245
 
 
246
 
   /*
247
 
    * TODO: Enable DCC for storage images on GFX9 and earlier.
248
 
    *
249
 
    * Also disable DCC with atomics because even when DCC stores are
250
 
    * supported atomics will always decompress. So if we are
251
 
    * decompressing a lot anyway we might as well not have DCC.
252
 
    */
253
 
   if ((pCreateInfo->usage & VK_IMAGE_USAGE_STORAGE_BIT) &&
254
 
       (device->physical_device->rad_info.chip_class < GFX10 ||
255
 
        radv_formats_is_atomic_allowed(device, pCreateInfo->pNext, format, pCreateInfo->flags)))
256
 
      return false;
257
 
 
258
 
   /* Do not enable DCC for fragment shading rate attachments. */
259
 
   if (pCreateInfo->usage & VK_IMAGE_USAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR)
260
 
      return false;
261
 
 
262
 
   if (pCreateInfo->tiling == VK_IMAGE_TILING_LINEAR)
263
 
      return false;
264
 
 
265
 
   if (vk_format_is_subsampled(format) || vk_format_get_plane_count(format) > 1)
266
 
      return false;
267
 
 
268
 
   if (!radv_image_use_fast_clear_for_image_early(device, image) &&
269
 
       image->tiling != VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT)
270
 
      return false;
271
 
 
272
 
   /* Do not enable DCC for mipmapped arrays because performance is worse. */
273
 
   if (pCreateInfo->arrayLayers > 1 && pCreateInfo->mipLevels > 1)
274
 
      return false;
275
 
 
276
 
   if (device->physical_device->rad_info.chip_class < GFX10) {
277
 
      /* TODO: Add support for DCC MSAA on GFX8-9. */
278
 
      if (pCreateInfo->samples > 1 && !device->physical_device->dcc_msaa_allowed)
279
 
         return false;
280
 
 
281
 
      /* TODO: Add support for DCC layers/mipmaps on GFX9. */
282
 
      if ((pCreateInfo->arrayLayers > 1 || pCreateInfo->mipLevels > 1) &&
283
 
          device->physical_device->rad_info.chip_class == GFX9)
284
 
         return false;
285
 
   }
286
 
 
287
 
   return radv_are_formats_dcc_compatible(device->physical_device, pCreateInfo->pNext, format,
288
 
                                          pCreateInfo->flags, sign_reinterpret);
289
 
}
290
 
 
291
 
static bool
292
 
radv_use_dcc_for_image_late(struct radv_device *device, struct radv_image *image)
293
 
{
294
 
   if (!radv_image_has_dcc(image))
295
 
      return false;
296
 
 
297
 
   if (image->tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT)
298
 
      return true;
299
 
 
300
 
   if (!radv_image_use_fast_clear_for_image(device, image))
301
 
      return false;
302
 
 
303
 
   /* TODO: Fix storage images with DCC without DCC image stores.
304
 
    * Disabling it for now. */
305
 
   if ((image->usage & VK_IMAGE_USAGE_STORAGE_BIT) && !radv_image_use_dcc_image_stores(device, image))
306
 
      return false;
307
 
 
308
 
   return true;
309
 
}
310
 
 
311
 
/*
312
 
 * Whether to enable image stores with DCC compression for this image. If
313
 
 * this function returns false the image subresource should be decompressed
314
 
 * before using it with image stores.
315
 
 *
316
 
 * Note that this can have mixed performance implications, see
317
 
 * https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6796#note_643299
318
 
 *
319
 
 * This function assumes the image uses DCC compression.
320
 
 */
321
 
bool
322
 
radv_image_use_dcc_image_stores(const struct radv_device *device, const struct radv_image *image)
323
 
{
324
 
   return ac_surface_supports_dcc_image_stores(device->physical_device->rad_info.chip_class,
325
 
                                               &image->planes[0].surface);
326
 
}
327
 
 
328
 
/*
329
 
 * Whether to use a predicate to determine whether DCC is in a compressed
330
 
 * state. This can be used to avoid decompressing an image multiple times.
331
 
 */
332
 
bool
333
 
radv_image_use_dcc_predication(const struct radv_device *device, const struct radv_image *image)
334
 
{
335
 
   return radv_image_has_dcc(image) && !radv_image_use_dcc_image_stores(device, image);
336
 
}
337
 
 
338
 
static inline bool
339
 
radv_use_fmask_for_image(const struct radv_device *device, const struct radv_image *image)
340
 
{
341
 
   return image->info.samples > 1 && ((image->usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) ||
342
 
                                      (device->instance->debug_flags & RADV_DEBUG_FORCE_COMPRESS));
343
 
}
344
 
 
345
 
static inline bool
346
 
radv_use_htile_for_image(const struct radv_device *device, const struct radv_image *image)
347
 
{
348
 
   /* TODO:
349
 
    * - Investigate about mips+layers.
350
 
    * - Enable on other gens.
351
 
    */
352
 
   bool use_htile_for_mips =
353
 
      image->info.array_size == 1 && device->physical_device->rad_info.chip_class >= GFX10;
354
 
 
355
 
   /* Stencil texturing with HTILE doesn't work with mipmapping on Navi10-14. */
356
 
   if (device->physical_device->rad_info.chip_class == GFX10 &&
357
 
       image->vk_format == VK_FORMAT_D32_SFLOAT_S8_UINT && image->info.levels > 1)
358
 
      return false;
359
 
 
360
 
   /* Do not enable HTILE for very small images because it seems less performant but make sure it's
361
 
    * allowed with VRS attachments because we need HTILE.
362
 
    */
363
 
   if (image->info.width * image->info.height < 8 * 8 &&
364
 
       !(device->instance->debug_flags & RADV_DEBUG_FORCE_COMPRESS) &&
365
 
       !device->attachment_vrs_enabled)
366
 
      return false;
367
 
 
368
 
   if (device->instance->disable_htile_layers && image->info.array_size > 1)
369
 
      return false;
370
 
 
371
 
   return (image->info.levels == 1 || use_htile_for_mips) && !image->shareable;
372
 
}
373
 
 
374
 
static bool
375
 
radv_use_tc_compat_cmask_for_image(struct radv_device *device, struct radv_image *image)
376
 
{
377
 
   /* TC-compat CMASK is only available for GFX8+. */
378
 
   if (device->physical_device->rad_info.chip_class < GFX8)
379
 
      return false;
380
 
 
381
 
   if (device->instance->debug_flags & RADV_DEBUG_NO_TC_COMPAT_CMASK)
382
 
      return false;
383
 
 
384
 
   /* TC-compat CMASK with storage images is supported on GFX10+. */
385
 
   if ((image->usage & VK_IMAGE_USAGE_STORAGE_BIT) &&
386
 
       device->physical_device->rad_info.chip_class < GFX10)
387
 
      return false;
388
 
 
389
 
   /* Do not enable TC-compatible if the image isn't readable by a shader
390
 
    * because no texture fetches will happen.
391
 
    */
392
 
   if (!(image->usage & (VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT |
393
 
                         VK_IMAGE_USAGE_TRANSFER_SRC_BIT)))
394
 
      return false;
395
 
 
396
 
   /* If the image doesn't have FMASK, it can't be fetchable. */
397
 
   if (!radv_image_has_fmask(image))
398
 
      return false;
399
 
 
400
 
   return true;
401
 
}
402
 
 
403
 
static uint32_t
404
 
si_get_bo_metadata_word1(const struct radv_device *device)
405
 
{
406
 
   return (ATI_VENDOR_ID << 16) | device->physical_device->rad_info.pci_id;
407
 
}
408
 
 
409
 
static bool
410
 
radv_is_valid_opaque_metadata(const struct radv_device *device, const struct radeon_bo_metadata *md)
411
 
{
412
 
   if (md->metadata[0] != 1 || md->metadata[1] != si_get_bo_metadata_word1(device))
413
 
      return false;
414
 
 
415
 
   if (md->size_metadata < 40)
416
 
      return false;
417
 
 
418
 
   return true;
419
 
}
420
 
 
421
 
static void
422
 
radv_patch_surface_from_metadata(struct radv_device *device, struct radeon_surf *surface,
423
 
                                 const struct radeon_bo_metadata *md)
424
 
{
425
 
   surface->flags = RADEON_SURF_CLR(surface->flags, MODE);
426
 
 
427
 
   if (device->physical_device->rad_info.chip_class >= GFX9) {
428
 
      if (md->u.gfx9.swizzle_mode > 0)
429
 
         surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE);
430
 
      else
431
 
         surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_LINEAR_ALIGNED, MODE);
432
 
 
433
 
      surface->u.gfx9.swizzle_mode = md->u.gfx9.swizzle_mode;
434
 
   } else {
435
 
      surface->u.legacy.pipe_config = md->u.legacy.pipe_config;
436
 
      surface->u.legacy.bankw = md->u.legacy.bankw;
437
 
      surface->u.legacy.bankh = md->u.legacy.bankh;
438
 
      surface->u.legacy.tile_split = md->u.legacy.tile_split;
439
 
      surface->u.legacy.mtilea = md->u.legacy.mtilea;
440
 
      surface->u.legacy.num_banks = md->u.legacy.num_banks;
441
 
 
442
 
      if (md->u.legacy.macrotile == RADEON_LAYOUT_TILED)
443
 
         surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE);
444
 
      else if (md->u.legacy.microtile == RADEON_LAYOUT_TILED)
445
 
         surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE);
446
 
      else
447
 
         surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_LINEAR_ALIGNED, MODE);
448
 
   }
449
 
}
450
 
 
451
 
static VkResult
452
 
radv_patch_image_dimensions(struct radv_device *device, struct radv_image *image,
453
 
                            const struct radv_image_create_info *create_info,
454
 
                            struct ac_surf_info *image_info)
455
 
{
456
 
   unsigned width = image->info.width;
457
 
   unsigned height = image->info.height;
458
 
 
459
 
   /*
460
 
    * minigbm sometimes allocates bigger images which is going to result in
461
 
    * weird strides and other properties. Lets be lenient where possible and
462
 
    * fail it on GFX10 (as we cannot cope there).
463
 
    *
464
 
    * Example hack: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/1457777/
465
 
    */
466
 
   if (create_info->bo_metadata &&
467
 
       radv_is_valid_opaque_metadata(device, create_info->bo_metadata)) {
468
 
      const struct radeon_bo_metadata *md = create_info->bo_metadata;
469
 
 
470
 
      if (device->physical_device->rad_info.chip_class >= GFX10) {
471
 
         width = G_00A004_WIDTH_LO(md->metadata[3]) + (G_00A008_WIDTH_HI(md->metadata[4]) << 2) + 1;
472
 
         height = G_00A008_HEIGHT(md->metadata[4]) + 1;
473
 
      } else {
474
 
         width = G_008F18_WIDTH(md->metadata[4]) + 1;
475
 
         height = G_008F18_HEIGHT(md->metadata[4]) + 1;
476
 
      }
477
 
   }
478
 
 
479
 
   if (image->info.width == width && image->info.height == height)
480
 
      return VK_SUCCESS;
481
 
 
482
 
   if (width < image->info.width || height < image->info.height) {
483
 
      fprintf(stderr,
484
 
              "The imported image has smaller dimensions than the internal\n"
485
 
              "dimensions. Using it is going to fail badly, so we reject\n"
486
 
              "this import.\n"
487
 
              "(internal dimensions: %d x %d, external dimensions: %d x %d)\n",
488
 
              image->info.width, image->info.height, width, height);
489
 
      return VK_ERROR_INVALID_EXTERNAL_HANDLE;
490
 
   } else if (device->physical_device->rad_info.chip_class >= GFX10) {
491
 
      fprintf(stderr,
492
 
              "Tried to import an image with inconsistent width on GFX10.\n"
493
 
              "As GFX10 has no separate stride fields we cannot cope with\n"
494
 
              "an inconsistency in width and will fail this import.\n"
495
 
              "(internal dimensions: %d x %d, external dimensions: %d x %d)\n",
496
 
              image->info.width, image->info.height, width, height);
497
 
      return VK_ERROR_INVALID_EXTERNAL_HANDLE;
498
 
   } else {
499
 
      fprintf(stderr,
500
 
              "Tried to import an image with inconsistent width on pre-GFX10.\n"
501
 
              "As GFX10 has no separate stride fields we cannot cope with\n"
502
 
              "an inconsistency and would fail on GFX10.\n"
503
 
              "(internal dimensions: %d x %d, external dimensions: %d x %d)\n",
504
 
              image->info.width, image->info.height, width, height);
505
 
   }
506
 
   image_info->width = width;
507
 
   image_info->height = height;
508
 
 
509
 
   return VK_SUCCESS;
510
 
}
511
 
 
512
 
static VkResult
513
 
radv_patch_image_from_extra_info(struct radv_device *device, struct radv_image *image,
514
 
                                 const struct radv_image_create_info *create_info,
515
 
                                 struct ac_surf_info *image_info)
516
 
{
517
 
   VkResult result = radv_patch_image_dimensions(device, image, create_info, image_info);
518
 
   if (result != VK_SUCCESS)
519
 
      return result;
520
 
 
521
 
   for (unsigned plane = 0; plane < image->plane_count; ++plane) {
522
 
      if (create_info->bo_metadata) {
523
 
         radv_patch_surface_from_metadata(device, &image->planes[plane].surface,
524
 
                                          create_info->bo_metadata);
525
 
      }
526
 
 
527
 
      if (radv_surface_has_scanout(device, create_info)) {
528
 
         image->planes[plane].surface.flags |= RADEON_SURF_SCANOUT;
529
 
         if (device->instance->debug_flags & RADV_DEBUG_NO_DISPLAY_DCC)
530
 
            image->planes[plane].surface.flags |= RADEON_SURF_DISABLE_DCC;
531
 
 
532
 
         image->info.surf_index = NULL;
533
 
      }
534
 
 
535
 
      if (create_info->prime_blit_src && device->physical_device->rad_info.chip_class == GFX9) {
536
 
         /* Older SDMA hw can't handle DCC */
537
 
         image->planes[plane].surface.flags |= RADEON_SURF_DISABLE_DCC;
538
 
      }
539
 
   }
540
 
   return VK_SUCCESS;
541
 
}
542
 
 
543
 
static VkFormat
544
 
etc2_emulation_format(VkFormat format)
545
 
{
546
 
   switch (format) {
547
 
   case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK:
548
 
   case VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK:
549
 
   case VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK:
550
 
      return VK_FORMAT_R8G8B8A8_UNORM;
551
 
   case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK:
552
 
   case VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK:
553
 
   case VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK:
554
 
      return VK_FORMAT_R8G8B8A8_SRGB;
555
 
   case VK_FORMAT_EAC_R11_UNORM_BLOCK:
556
 
      return VK_FORMAT_R16_UNORM;
557
 
   case VK_FORMAT_EAC_R11_SNORM_BLOCK:
558
 
      return VK_FORMAT_R16_SNORM;
559
 
   case VK_FORMAT_EAC_R11G11_UNORM_BLOCK:
560
 
      return VK_FORMAT_R16G16_UNORM;
561
 
   case VK_FORMAT_EAC_R11G11_SNORM_BLOCK:
562
 
      return VK_FORMAT_R16G16_SNORM;
563
 
   default:
564
 
      unreachable("Unhandled ETC format");
565
 
   }
566
 
}
567
 
 
568
 
static VkFormat
569
 
radv_image_get_plane_format(const struct radv_physical_device *pdev, const struct radv_image *image,
570
 
                            unsigned plane)
571
 
{
572
 
   if (pdev->emulate_etc2 &&
573
 
       vk_format_description(image->vk_format)->layout == UTIL_FORMAT_LAYOUT_ETC) {
574
 
      if (plane == 0)
575
 
         return image->vk_format;
576
 
      return etc2_emulation_format(image->vk_format);
577
 
   }
578
 
   return vk_format_get_plane_format(image->vk_format, plane);
579
 
}
580
 
 
581
 
static uint64_t
582
 
radv_get_surface_flags(struct radv_device *device, struct radv_image *image, unsigned plane_id,
583
 
                       const VkImageCreateInfo *pCreateInfo, VkFormat image_format)
584
 
{
585
 
   uint64_t flags;
586
 
   unsigned array_mode = radv_choose_tiling(device, pCreateInfo, image_format);
587
 
   VkFormat format = radv_image_get_plane_format(device->physical_device, image, plane_id);
588
 
   const struct util_format_description *desc = vk_format_description(format);
589
 
   bool is_depth, is_stencil;
590
 
 
591
 
   is_depth = util_format_has_depth(desc);
592
 
   is_stencil = util_format_has_stencil(desc);
593
 
 
594
 
   flags = RADEON_SURF_SET(array_mode, MODE);
595
 
 
596
 
   switch (pCreateInfo->imageType) {
597
 
   case VK_IMAGE_TYPE_1D:
598
 
      if (pCreateInfo->arrayLayers > 1)
599
 
         flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_1D_ARRAY, TYPE);
600
 
      else
601
 
         flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_1D, TYPE);
602
 
      break;
603
 
   case VK_IMAGE_TYPE_2D:
604
 
      if (pCreateInfo->arrayLayers > 1)
605
 
         flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_2D_ARRAY, TYPE);
606
 
      else
607
 
         flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_2D, TYPE);
608
 
      break;
609
 
   case VK_IMAGE_TYPE_3D:
610
 
      flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_3D, TYPE);
611
 
      break;
612
 
   default:
613
 
      unreachable("unhandled image type");
614
 
   }
615
 
 
616
 
   /* Required for clearing/initializing a specific layer on GFX8. */
617
 
   flags |= RADEON_SURF_CONTIGUOUS_DCC_LAYERS;
618
 
 
619
 
   if (is_depth) {
620
 
      flags |= RADEON_SURF_ZBUFFER;
621
 
 
622
 
      if (radv_use_htile_for_image(device, image) &&
623
 
          !(device->instance->debug_flags & RADV_DEBUG_NO_HIZ)) {
624
 
         if (radv_use_tc_compat_htile_for_image(device, pCreateInfo, image_format))
625
 
            flags |= RADEON_SURF_TC_COMPATIBLE_HTILE;
626
 
      } else {
627
 
         flags |= RADEON_SURF_NO_HTILE;
628
 
      }
629
 
   }
630
 
 
631
 
   if (is_stencil)
632
 
      flags |= RADEON_SURF_SBUFFER;
633
 
 
634
 
   if (device->physical_device->rad_info.chip_class >= GFX9 &&
635
 
       pCreateInfo->imageType == VK_IMAGE_TYPE_3D &&
636
 
       vk_format_get_blocksizebits(image_format) == 128 && vk_format_is_compressed(image_format))
637
 
      flags |= RADEON_SURF_NO_RENDER_TARGET;
638
 
 
639
 
   if (!radv_use_dcc_for_image_early(device, image, pCreateInfo, image_format,
640
 
                                     &image->dcc_sign_reinterpret))
641
 
      flags |= RADEON_SURF_DISABLE_DCC;
642
 
 
643
 
   if (!radv_use_fmask_for_image(device, image))
644
 
      flags |= RADEON_SURF_NO_FMASK;
645
 
 
646
 
   if (pCreateInfo->flags & VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT) {
647
 
      flags |=
648
 
         RADEON_SURF_PRT | RADEON_SURF_NO_FMASK | RADEON_SURF_NO_HTILE | RADEON_SURF_DISABLE_DCC;
649
 
   }
650
 
 
651
 
   return flags;
652
 
}
653
 
 
654
 
static inline unsigned
655
 
si_tile_mode_index(const struct radv_image_plane *plane, unsigned level, bool stencil)
656
 
{
657
 
   if (stencil)
658
 
      return plane->surface.u.legacy.zs.stencil_tiling_index[level];
659
 
   else
660
 
      return plane->surface.u.legacy.tiling_index[level];
661
 
}
662
 
 
663
 
static unsigned
664
 
radv_map_swizzle(unsigned swizzle)
665
 
{
666
 
   switch (swizzle) {
667
 
   case PIPE_SWIZZLE_Y:
668
 
      return V_008F0C_SQ_SEL_Y;
669
 
   case PIPE_SWIZZLE_Z:
670
 
      return V_008F0C_SQ_SEL_Z;
671
 
   case PIPE_SWIZZLE_W:
672
 
      return V_008F0C_SQ_SEL_W;
673
 
   case PIPE_SWIZZLE_0:
674
 
      return V_008F0C_SQ_SEL_0;
675
 
   case PIPE_SWIZZLE_1:
676
 
      return V_008F0C_SQ_SEL_1;
677
 
   default: /* PIPE_SWIZZLE_X */
678
 
      return V_008F0C_SQ_SEL_X;
679
 
   }
680
 
}
681
 
 
682
 
static void
683
 
radv_compose_swizzle(const struct util_format_description *desc, const VkComponentMapping *mapping,
684
 
                     enum pipe_swizzle swizzle[4])
685
 
{
686
 
   if (desc->format == PIPE_FORMAT_R64_UINT || desc->format == PIPE_FORMAT_R64_SINT) {
687
 
      /* 64-bit formats only support storage images and storage images
688
 
       * require identity component mappings. We use 32-bit
689
 
       * instructions to access 64-bit images, so we need a special
690
 
       * case here.
691
 
       *
692
 
       * The zw components are 1,0 so that they can be easily be used
693
 
       * by loads to create the w component, which has to be 0 for
694
 
       * NULL descriptors.
695
 
       */
696
 
      swizzle[0] = PIPE_SWIZZLE_X;
697
 
      swizzle[1] = PIPE_SWIZZLE_Y;
698
 
      swizzle[2] = PIPE_SWIZZLE_1;
699
 
      swizzle[3] = PIPE_SWIZZLE_0;
700
 
   } else if (!mapping) {
701
 
      for (unsigned i = 0; i < 4; i++)
702
 
         swizzle[i] = desc->swizzle[i];
703
 
   } else if (desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS) {
704
 
      const unsigned char swizzle_xxxx[4] = {PIPE_SWIZZLE_X, PIPE_SWIZZLE_0, PIPE_SWIZZLE_0,
705
 
                                             PIPE_SWIZZLE_1};
706
 
      vk_format_compose_swizzles(mapping, swizzle_xxxx, swizzle);
707
 
   } else {
708
 
      vk_format_compose_swizzles(mapping, desc->swizzle, swizzle);
709
 
   }
710
 
}
711
 
 
712
 
static void
713
 
radv_make_buffer_descriptor(struct radv_device *device, struct radv_buffer *buffer,
714
 
                            VkFormat vk_format, unsigned offset, unsigned range, uint32_t *state)
715
 
{
716
 
   const struct util_format_description *desc;
717
 
   unsigned stride;
718
 
   uint64_t gpu_address = radv_buffer_get_va(buffer->bo);
719
 
   uint64_t va = gpu_address + buffer->offset;
720
 
   unsigned num_format, data_format;
721
 
   int first_non_void;
722
 
   enum pipe_swizzle swizzle[4];
723
 
   desc = vk_format_description(vk_format);
724
 
   first_non_void = vk_format_get_first_non_void_channel(vk_format);
725
 
   stride = desc->block.bits / 8;
726
 
 
727
 
   radv_compose_swizzle(desc, NULL, swizzle);
728
 
 
729
 
   va += offset;
730
 
   state[0] = va;
731
 
   state[1] = S_008F04_BASE_ADDRESS_HI(va >> 32) | S_008F04_STRIDE(stride);
732
 
 
733
 
   if (device->physical_device->rad_info.chip_class != GFX8 && stride) {
734
 
      range /= stride;
735
 
   }
736
 
 
737
 
   state[2] = range;
738
 
   state[3] = S_008F0C_DST_SEL_X(radv_map_swizzle(swizzle[0])) |
739
 
              S_008F0C_DST_SEL_Y(radv_map_swizzle(swizzle[1])) |
740
 
              S_008F0C_DST_SEL_Z(radv_map_swizzle(swizzle[2])) |
741
 
              S_008F0C_DST_SEL_W(radv_map_swizzle(swizzle[3]));
742
 
 
743
 
   if (device->physical_device->rad_info.chip_class >= GFX10) {
744
 
      const struct gfx10_format *fmt = &gfx10_format_table[vk_format_to_pipe_format(vk_format)];
745
 
 
746
 
      /* OOB_SELECT chooses the out-of-bounds check:
747
 
       *  - 0: (index >= NUM_RECORDS) || (offset >= STRIDE)
748
 
       *  - 1: index >= NUM_RECORDS
749
 
       *  - 2: NUM_RECORDS == 0
750
 
       *  - 3: if SWIZZLE_ENABLE == 0: offset >= NUM_RECORDS
751
 
       *       else: swizzle_address >= NUM_RECORDS
752
 
       */
753
 
      state[3] |= S_008F0C_FORMAT(fmt->img_format) |
754
 
                  S_008F0C_OOB_SELECT(V_008F0C_OOB_SELECT_STRUCTURED_WITH_OFFSET) |
755
 
                  S_008F0C_RESOURCE_LEVEL(1);
756
 
   } else {
757
 
      num_format = radv_translate_buffer_numformat(desc, first_non_void);
758
 
      data_format = radv_translate_buffer_dataformat(desc, first_non_void);
759
 
 
760
 
      assert(data_format != V_008F0C_BUF_DATA_FORMAT_INVALID);
761
 
      assert(num_format != ~0);
762
 
 
763
 
      state[3] |= S_008F0C_NUM_FORMAT(num_format) | S_008F0C_DATA_FORMAT(data_format);
764
 
   }
765
 
}
766
 
 
767
 
static void
768
 
si_set_mutable_tex_desc_fields(struct radv_device *device, struct radv_image *image,
769
 
                               const struct legacy_surf_level *base_level_info, unsigned plane_id,
770
 
                               unsigned base_level, unsigned first_level, unsigned block_width,
771
 
                               bool is_stencil, bool is_storage_image, bool disable_compression,
772
 
                               bool enable_write_compression, uint32_t *state)
773
 
{
774
 
   struct radv_image_plane *plane = &image->planes[plane_id];
775
 
   uint64_t gpu_address = image->bo ? radv_buffer_get_va(image->bo) + image->offset : 0;
776
 
   uint64_t va = gpu_address;
777
 
   enum chip_class chip_class = device->physical_device->rad_info.chip_class;
778
 
   uint64_t meta_va = 0;
779
 
   if (chip_class >= GFX9) {
780
 
      if (is_stencil)
781
 
         va += plane->surface.u.gfx9.zs.stencil_offset;
782
 
      else
783
 
         va += plane->surface.u.gfx9.surf_offset;
784
 
   } else
785
 
      va += (uint64_t)base_level_info->offset_256B * 256;
786
 
 
787
 
   state[0] = va >> 8;
788
 
   if (chip_class >= GFX9 || base_level_info->mode == RADEON_SURF_MODE_2D)
789
 
      state[0] |= plane->surface.tile_swizzle;
790
 
   state[1] &= C_008F14_BASE_ADDRESS_HI;
791
 
   state[1] |= S_008F14_BASE_ADDRESS_HI(va >> 40);
792
 
 
793
 
   if (chip_class >= GFX8) {
794
 
      state[6] &= C_008F28_COMPRESSION_EN;
795
 
      state[7] = 0;
796
 
      if (!disable_compression && radv_dcc_enabled(image, first_level)) {
797
 
         meta_va = gpu_address + plane->surface.meta_offset;
798
 
         if (chip_class <= GFX8)
799
 
            meta_va += plane->surface.u.legacy.color.dcc_level[base_level].dcc_offset;
800
 
 
801
 
         unsigned dcc_tile_swizzle = plane->surface.tile_swizzle << 8;
802
 
         dcc_tile_swizzle &= (1 << plane->surface.meta_alignment_log2) - 1;
803
 
         meta_va |= dcc_tile_swizzle;
804
 
      } else if (!disable_compression && radv_image_is_tc_compat_htile(image)) {
805
 
         meta_va = gpu_address + plane->surface.meta_offset;
806
 
      }
807
 
 
808
 
      if (meta_va) {
809
 
         state[6] |= S_008F28_COMPRESSION_EN(1);
810
 
         if (chip_class <= GFX9)
811
 
            state[7] = meta_va >> 8;
812
 
      }
813
 
   }
814
 
 
815
 
   if (chip_class >= GFX10) {
816
 
      state[3] &= C_00A00C_SW_MODE;
817
 
 
818
 
      if (is_stencil) {
819
 
         state[3] |= S_00A00C_SW_MODE(plane->surface.u.gfx9.zs.stencil_swizzle_mode);
820
 
      } else {
821
 
         state[3] |= S_00A00C_SW_MODE(plane->surface.u.gfx9.swizzle_mode);
822
 
      }
823
 
 
824
 
      state[6] &= C_00A018_META_DATA_ADDRESS_LO & C_00A018_META_PIPE_ALIGNED;
825
 
 
826
 
      if (meta_va) {
827
 
         struct gfx9_surf_meta_flags meta = {
828
 
            .rb_aligned = 1,
829
 
            .pipe_aligned = 1,
830
 
         };
831
 
 
832
 
         if (!(plane->surface.flags & RADEON_SURF_Z_OR_SBUFFER))
833
 
            meta = plane->surface.u.gfx9.color.dcc;
834
 
 
835
 
         if (radv_dcc_enabled(image, first_level) && is_storage_image && enable_write_compression)
836
 
            state[6] |= S_00A018_WRITE_COMPRESS_ENABLE(1);
837
 
 
838
 
         state[6] |= S_00A018_META_PIPE_ALIGNED(meta.pipe_aligned) |
839
 
                     S_00A018_META_DATA_ADDRESS_LO(meta_va >> 8);
840
 
      }
841
 
 
842
 
      state[7] = meta_va >> 16;
843
 
   } else if (chip_class == GFX9) {
844
 
      state[3] &= C_008F1C_SW_MODE;
845
 
      state[4] &= C_008F20_PITCH;
846
 
 
847
 
      if (is_stencil) {
848
 
         state[3] |= S_008F1C_SW_MODE(plane->surface.u.gfx9.zs.stencil_swizzle_mode);
849
 
         state[4] |= S_008F20_PITCH(plane->surface.u.gfx9.zs.stencil_epitch);
850
 
      } else {
851
 
         state[3] |= S_008F1C_SW_MODE(plane->surface.u.gfx9.swizzle_mode);
852
 
         state[4] |= S_008F20_PITCH(plane->surface.u.gfx9.epitch);
853
 
      }
854
 
 
855
 
      state[5] &=
856
 
         C_008F24_META_DATA_ADDRESS & C_008F24_META_PIPE_ALIGNED & C_008F24_META_RB_ALIGNED;
857
 
      if (meta_va) {
858
 
         struct gfx9_surf_meta_flags meta = {
859
 
            .rb_aligned = 1,
860
 
            .pipe_aligned = 1,
861
 
         };
862
 
 
863
 
         if (!(plane->surface.flags & RADEON_SURF_Z_OR_SBUFFER))
864
 
            meta = plane->surface.u.gfx9.color.dcc;
865
 
 
866
 
         state[5] |= S_008F24_META_DATA_ADDRESS(meta_va >> 40) |
867
 
                     S_008F24_META_PIPE_ALIGNED(meta.pipe_aligned) |
868
 
                     S_008F24_META_RB_ALIGNED(meta.rb_aligned);
869
 
      }
870
 
   } else {
871
 
      /* GFX6-GFX8 */
872
 
      unsigned pitch = base_level_info->nblk_x * block_width;
873
 
      unsigned index = si_tile_mode_index(plane, base_level, is_stencil);
874
 
 
875
 
      state[3] &= C_008F1C_TILING_INDEX;
876
 
      state[3] |= S_008F1C_TILING_INDEX(index);
877
 
      state[4] &= C_008F20_PITCH;
878
 
      state[4] |= S_008F20_PITCH(pitch - 1);
879
 
   }
880
 
}
881
 
 
882
 
static unsigned
883
 
radv_tex_dim(VkImageType image_type, VkImageViewType view_type, unsigned nr_layers,
884
 
             unsigned nr_samples, bool is_storage_image, bool gfx9)
885
 
{
886
 
   if (view_type == VK_IMAGE_VIEW_TYPE_CUBE || view_type == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
887
 
      return is_storage_image ? V_008F1C_SQ_RSRC_IMG_2D_ARRAY : V_008F1C_SQ_RSRC_IMG_CUBE;
888
 
 
889
 
   /* GFX9 allocates 1D textures as 2D. */
890
 
   if (gfx9 && image_type == VK_IMAGE_TYPE_1D)
891
 
      image_type = VK_IMAGE_TYPE_2D;
892
 
   switch (image_type) {
893
 
   case VK_IMAGE_TYPE_1D:
894
 
      return nr_layers > 1 ? V_008F1C_SQ_RSRC_IMG_1D_ARRAY : V_008F1C_SQ_RSRC_IMG_1D;
895
 
   case VK_IMAGE_TYPE_2D:
896
 
      if (nr_samples > 1)
897
 
         return nr_layers > 1 ? V_008F1C_SQ_RSRC_IMG_2D_MSAA_ARRAY : V_008F1C_SQ_RSRC_IMG_2D_MSAA;
898
 
      else
899
 
         return nr_layers > 1 ? V_008F1C_SQ_RSRC_IMG_2D_ARRAY : V_008F1C_SQ_RSRC_IMG_2D;
900
 
   case VK_IMAGE_TYPE_3D:
901
 
      if (view_type == VK_IMAGE_VIEW_TYPE_3D)
902
 
         return V_008F1C_SQ_RSRC_IMG_3D;
903
 
      else
904
 
         return V_008F1C_SQ_RSRC_IMG_2D_ARRAY;
905
 
   default:
906
 
      unreachable("illegal image type");
907
 
   }
908
 
}
909
 
 
910
 
static unsigned
911
 
gfx9_border_color_swizzle(const struct util_format_description *desc)
912
 
{
913
 
   unsigned bc_swizzle = V_008F20_BC_SWIZZLE_XYZW;
914
 
 
915
 
   if (desc->swizzle[3] == PIPE_SWIZZLE_X) {
916
 
      /* For the pre-defined border color values (white, opaque
917
 
       * black, transparent black), the only thing that matters is
918
 
       * that the alpha channel winds up in the correct place
919
 
       * (because the RGB channels are all the same) so either of
920
 
       * these enumerations will work.
921
 
       */
922
 
      if (desc->swizzle[2] == PIPE_SWIZZLE_Y)
923
 
         bc_swizzle = V_008F20_BC_SWIZZLE_WZYX;
924
 
      else
925
 
         bc_swizzle = V_008F20_BC_SWIZZLE_WXYZ;
926
 
   } else if (desc->swizzle[0] == PIPE_SWIZZLE_X) {
927
 
      if (desc->swizzle[1] == PIPE_SWIZZLE_Y)
928
 
         bc_swizzle = V_008F20_BC_SWIZZLE_XYZW;
929
 
      else
930
 
         bc_swizzle = V_008F20_BC_SWIZZLE_XWYZ;
931
 
   } else if (desc->swizzle[1] == PIPE_SWIZZLE_X) {
932
 
      bc_swizzle = V_008F20_BC_SWIZZLE_YXWZ;
933
 
   } else if (desc->swizzle[2] == PIPE_SWIZZLE_X) {
934
 
      bc_swizzle = V_008F20_BC_SWIZZLE_ZYXW;
935
 
   }
936
 
 
937
 
   return bc_swizzle;
938
 
}
939
 
 
940
 
bool
941
 
vi_alpha_is_on_msb(struct radv_device *device, VkFormat format)
942
 
{
943
 
   const struct util_format_description *desc = vk_format_description(format);
944
 
 
945
 
   if (device->physical_device->rad_info.chip_class >= GFX10 && desc->nr_channels == 1)
946
 
      return desc->swizzle[3] == PIPE_SWIZZLE_X;
947
 
 
948
 
   return radv_translate_colorswap(format, false) <= 1;
949
 
}
950
 
/**
951
 
 * Build the sampler view descriptor for a texture (GFX10).
952
 
 */
953
 
static void
954
 
gfx10_make_texture_descriptor(struct radv_device *device, struct radv_image *image,
955
 
                              bool is_storage_image, VkImageViewType view_type, VkFormat vk_format,
956
 
                              const VkComponentMapping *mapping, unsigned first_level,
957
 
                              unsigned last_level, unsigned first_layer, unsigned last_layer,
958
 
                              unsigned width, unsigned height, unsigned depth, float min_lod,
959
 
                              uint32_t *state, uint32_t *fmask_state)
960
 
{
961
 
   const struct util_format_description *desc;
962
 
   enum pipe_swizzle swizzle[4];
963
 
   unsigned img_format;
964
 
   unsigned type;
965
 
 
966
 
   desc = vk_format_description(vk_format);
967
 
 
968
 
   /* For emulated ETC2 without alpha we need to override the format to a 3-componenent format, so
969
 
    * that border colors work correctly (alpha forced to 1). Since Vulkan has no such format,
970
 
    * this uses the Gallium formats to set the description. */
971
 
   if (image->vk_format == VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK &&
972
 
       vk_format == VK_FORMAT_R8G8B8A8_UNORM) {
973
 
      desc = util_format_description(PIPE_FORMAT_R8G8B8X8_UNORM);
974
 
   } else if (image->vk_format == VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK &&
975
 
              vk_format == VK_FORMAT_R8G8B8A8_SRGB) {
976
 
      desc = util_format_description(PIPE_FORMAT_R8G8B8X8_SRGB);
977
 
   }
978
 
 
979
 
   img_format = gfx10_format_table[vk_format_to_pipe_format(vk_format)].img_format;
980
 
 
981
 
   radv_compose_swizzle(desc, mapping, swizzle);
982
 
 
983
 
   type = radv_tex_dim(image->type, view_type, image->info.array_size, image->info.samples,
984
 
                       is_storage_image, device->physical_device->rad_info.chip_class == GFX9);
985
 
   if (type == V_008F1C_SQ_RSRC_IMG_1D_ARRAY) {
986
 
      height = 1;
987
 
      depth = image->info.array_size;
988
 
   } else if (type == V_008F1C_SQ_RSRC_IMG_2D_ARRAY || type == V_008F1C_SQ_RSRC_IMG_2D_MSAA_ARRAY) {
989
 
      if (view_type != VK_IMAGE_VIEW_TYPE_3D)
990
 
         depth = image->info.array_size;
991
 
   } else if (type == V_008F1C_SQ_RSRC_IMG_CUBE)
992
 
      depth = image->info.array_size / 6;
993
 
 
994
 
   state[0] = 0;
995
 
   state[1] = S_00A004_MIN_LOD(radv_float_to_ufixed(CLAMP(min_lod, 0, 15), 8)) |
996
 
              S_00A004_FORMAT(img_format) |
997
 
              S_00A004_WIDTH_LO(width - 1);
998
 
   state[2] = S_00A008_WIDTH_HI((width - 1) >> 2) | S_00A008_HEIGHT(height - 1) |
999
 
              S_00A008_RESOURCE_LEVEL(1);
1000
 
   state[3] = S_00A00C_DST_SEL_X(radv_map_swizzle(swizzle[0])) |
1001
 
              S_00A00C_DST_SEL_Y(radv_map_swizzle(swizzle[1])) |
1002
 
              S_00A00C_DST_SEL_Z(radv_map_swizzle(swizzle[2])) |
1003
 
              S_00A00C_DST_SEL_W(radv_map_swizzle(swizzle[3])) |
1004
 
              S_00A00C_BASE_LEVEL(image->info.samples > 1 ? 0 : first_level) |
1005
 
              S_00A00C_LAST_LEVEL(image->info.samples > 1 ? util_logbase2(image->info.samples)
1006
 
                                                          : last_level) |
1007
 
              S_00A00C_BC_SWIZZLE(gfx9_border_color_swizzle(desc)) | S_00A00C_TYPE(type);
1008
 
   /* Depth is the the last accessible layer on gfx9+. The hw doesn't need
1009
 
    * to know the total number of layers.
1010
 
    */
1011
 
   state[4] = S_00A010_DEPTH(type == V_008F1C_SQ_RSRC_IMG_3D ? depth - 1 : last_layer) |
1012
 
              S_00A010_BASE_ARRAY(first_layer);
1013
 
   state[5] = S_00A014_ARRAY_PITCH(0) |
1014
 
              S_00A014_MAX_MIP(image->info.samples > 1 ? util_logbase2(image->info.samples)
1015
 
                                                       : image->info.levels - 1) |
1016
 
              S_00A014_PERF_MOD(4);
1017
 
   state[6] = 0;
1018
 
   state[7] = 0;
1019
 
 
1020
 
   if (radv_dcc_enabled(image, first_level)) {
1021
 
      state[6] |= S_00A018_MAX_UNCOMPRESSED_BLOCK_SIZE(V_028C78_MAX_BLOCK_SIZE_256B) |
1022
 
                  S_00A018_MAX_COMPRESSED_BLOCK_SIZE(
1023
 
                     image->planes[0].surface.u.gfx9.color.dcc.max_compressed_block_size) |
1024
 
                  S_00A018_ALPHA_IS_ON_MSB(vi_alpha_is_on_msb(device, vk_format));
1025
 
   }
1026
 
 
1027
 
   if (radv_image_get_iterate256(device, image)) {
1028
 
      state[6] |= S_00A018_ITERATE_256(1);
1029
 
   }
1030
 
 
1031
 
   /* Initialize the sampler view for FMASK. */
1032
 
   if (fmask_state) {
1033
 
      if (radv_image_has_fmask(image)) {
1034
 
         uint64_t gpu_address = radv_buffer_get_va(image->bo);
1035
 
         uint32_t format;
1036
 
         uint64_t va;
1037
 
 
1038
 
         assert(image->plane_count == 1);
1039
 
 
1040
 
         va = gpu_address + image->offset + image->planes[0].surface.fmask_offset;
1041
 
 
1042
 
         switch (image->info.samples) {
1043
 
         case 2:
1044
 
            format = V_008F0C_GFX10_FORMAT_FMASK8_S2_F2;
1045
 
            break;
1046
 
         case 4:
1047
 
            format = V_008F0C_GFX10_FORMAT_FMASK8_S4_F4;
1048
 
            break;
1049
 
         case 8:
1050
 
            format = V_008F0C_GFX10_FORMAT_FMASK32_S8_F8;
1051
 
            break;
1052
 
         default:
1053
 
            unreachable("invalid nr_samples");
1054
 
         }
1055
 
 
1056
 
         fmask_state[0] = (va >> 8) | image->planes[0].surface.fmask_tile_swizzle;
1057
 
         fmask_state[1] = S_00A004_BASE_ADDRESS_HI(va >> 40) | S_00A004_FORMAT(format) |
1058
 
                          S_00A004_WIDTH_LO(width - 1);
1059
 
         fmask_state[2] = S_00A008_WIDTH_HI((width - 1) >> 2) | S_00A008_HEIGHT(height - 1) |
1060
 
                          S_00A008_RESOURCE_LEVEL(1);
1061
 
         fmask_state[3] =
1062
 
            S_00A00C_DST_SEL_X(V_008F1C_SQ_SEL_X) | S_00A00C_DST_SEL_Y(V_008F1C_SQ_SEL_X) |
1063
 
            S_00A00C_DST_SEL_Z(V_008F1C_SQ_SEL_X) | S_00A00C_DST_SEL_W(V_008F1C_SQ_SEL_X) |
1064
 
            S_00A00C_SW_MODE(image->planes[0].surface.u.gfx9.color.fmask_swizzle_mode) |
1065
 
            S_00A00C_TYPE(
1066
 
               radv_tex_dim(image->type, view_type, image->info.array_size, 0, false, false));
1067
 
         fmask_state[4] = S_00A010_DEPTH(last_layer) | S_00A010_BASE_ARRAY(first_layer);
1068
 
         fmask_state[5] = 0;
1069
 
         fmask_state[6] = S_00A018_META_PIPE_ALIGNED(1);
1070
 
         fmask_state[7] = 0;
1071
 
 
1072
 
         if (radv_image_is_tc_compat_cmask(image)) {
1073
 
            va = gpu_address + image->offset + image->planes[0].surface.cmask_offset;
1074
 
 
1075
 
            fmask_state[6] |= S_00A018_COMPRESSION_EN(1);
1076
 
            fmask_state[6] |= S_00A018_META_DATA_ADDRESS_LO(va >> 8);
1077
 
            fmask_state[7] |= va >> 16;
1078
 
         }
1079
 
      } else
1080
 
         memset(fmask_state, 0, 8 * 4);
1081
 
   }
1082
 
}
1083
 
 
1084
 
/**
1085
 
 * Build the sampler view descriptor for a texture (SI-GFX9)
1086
 
 */
1087
 
static void
1088
 
si_make_texture_descriptor(struct radv_device *device, struct radv_image *image,
1089
 
                           bool is_storage_image, VkImageViewType view_type, VkFormat vk_format,
1090
 
                           const VkComponentMapping *mapping, unsigned first_level,
1091
 
                           unsigned last_level, unsigned first_layer, unsigned last_layer,
1092
 
                           unsigned width, unsigned height, unsigned depth, float min_lod,
1093
 
                           uint32_t *state, uint32_t *fmask_state)
1094
 
{
1095
 
   const struct util_format_description *desc;
1096
 
   enum pipe_swizzle swizzle[4];
1097
 
   int first_non_void;
1098
 
   unsigned num_format, data_format, type;
1099
 
 
1100
 
   desc = vk_format_description(vk_format);
1101
 
 
1102
 
   /* For emulated ETC2 without alpha we need to override the format to a 3-componenent format, so
1103
 
    * that border colors work correctly (alpha forced to 1). Since Vulkan has no such format,
1104
 
    * this uses the Gallium formats to set the description. */
1105
 
   if (image->vk_format == VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK &&
1106
 
       vk_format == VK_FORMAT_R8G8B8A8_UNORM) {
1107
 
      desc = util_format_description(PIPE_FORMAT_R8G8B8X8_UNORM);
1108
 
   } else if (image->vk_format == VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK &&
1109
 
              vk_format == VK_FORMAT_R8G8B8A8_SRGB) {
1110
 
      desc = util_format_description(PIPE_FORMAT_R8G8B8X8_SRGB);
1111
 
   }
1112
 
 
1113
 
   radv_compose_swizzle(desc, mapping, swizzle);
1114
 
 
1115
 
   first_non_void = vk_format_get_first_non_void_channel(vk_format);
1116
 
 
1117
 
   num_format = radv_translate_tex_numformat(vk_format, desc, first_non_void);
1118
 
   if (num_format == ~0) {
1119
 
      num_format = 0;
1120
 
   }
1121
 
 
1122
 
   data_format = radv_translate_tex_dataformat(vk_format, desc, first_non_void);
1123
 
   if (data_format == ~0) {
1124
 
      data_format = 0;
1125
 
   }
1126
 
 
1127
 
   /* S8 with either Z16 or Z32 HTILE need a special format. */
1128
 
   if (device->physical_device->rad_info.chip_class == GFX9 && vk_format == VK_FORMAT_S8_UINT &&
1129
 
       radv_image_is_tc_compat_htile(image)) {
1130
 
      if (image->vk_format == VK_FORMAT_D32_SFLOAT_S8_UINT)
1131
 
         data_format = V_008F14_IMG_DATA_FORMAT_S8_32;
1132
 
      else if (image->vk_format == VK_FORMAT_D16_UNORM_S8_UINT)
1133
 
         data_format = V_008F14_IMG_DATA_FORMAT_S8_16;
1134
 
   }
1135
 
   type = radv_tex_dim(image->type, view_type, image->info.array_size, image->info.samples,
1136
 
                       is_storage_image, device->physical_device->rad_info.chip_class == GFX9);
1137
 
   if (type == V_008F1C_SQ_RSRC_IMG_1D_ARRAY) {
1138
 
      height = 1;
1139
 
      depth = image->info.array_size;
1140
 
   } else if (type == V_008F1C_SQ_RSRC_IMG_2D_ARRAY || type == V_008F1C_SQ_RSRC_IMG_2D_MSAA_ARRAY) {
1141
 
      if (view_type != VK_IMAGE_VIEW_TYPE_3D)
1142
 
         depth = image->info.array_size;
1143
 
   } else if (type == V_008F1C_SQ_RSRC_IMG_CUBE)
1144
 
      depth = image->info.array_size / 6;
1145
 
 
1146
 
   state[0] = 0;
1147
 
   state[1] = (S_008F14_MIN_LOD(radv_float_to_ufixed(CLAMP(min_lod, 0, 15), 8)) |
1148
 
               S_008F14_DATA_FORMAT(data_format) |
1149
 
               S_008F14_NUM_FORMAT(num_format));
1150
 
   state[2] = (S_008F18_WIDTH(width - 1) | S_008F18_HEIGHT(height - 1) | S_008F18_PERF_MOD(4));
1151
 
   state[3] = (S_008F1C_DST_SEL_X(radv_map_swizzle(swizzle[0])) |
1152
 
               S_008F1C_DST_SEL_Y(radv_map_swizzle(swizzle[1])) |
1153
 
               S_008F1C_DST_SEL_Z(radv_map_swizzle(swizzle[2])) |
1154
 
               S_008F1C_DST_SEL_W(radv_map_swizzle(swizzle[3])) |
1155
 
               S_008F1C_BASE_LEVEL(image->info.samples > 1 ? 0 : first_level) |
1156
 
               S_008F1C_LAST_LEVEL(image->info.samples > 1 ? util_logbase2(image->info.samples)
1157
 
                                                           : last_level) |
1158
 
               S_008F1C_TYPE(type));
1159
 
   state[4] = 0;
1160
 
   state[5] = S_008F24_BASE_ARRAY(first_layer);
1161
 
   state[6] = 0;
1162
 
   state[7] = 0;
1163
 
 
1164
 
   if (device->physical_device->rad_info.chip_class == GFX9) {
1165
 
      unsigned bc_swizzle = gfx9_border_color_swizzle(desc);
1166
 
 
1167
 
      /* Depth is the last accessible layer on Gfx9.
1168
 
       * The hw doesn't need to know the total number of layers.
1169
 
       */
1170
 
      if (type == V_008F1C_SQ_RSRC_IMG_3D)
1171
 
         state[4] |= S_008F20_DEPTH(depth - 1);
1172
 
      else
1173
 
         state[4] |= S_008F20_DEPTH(last_layer);
1174
 
 
1175
 
      state[4] |= S_008F20_BC_SWIZZLE(bc_swizzle);
1176
 
      state[5] |= S_008F24_MAX_MIP(image->info.samples > 1 ? util_logbase2(image->info.samples)
1177
 
                                                           : image->info.levels - 1);
1178
 
   } else {
1179
 
      state[3] |= S_008F1C_POW2_PAD(image->info.levels > 1);
1180
 
      state[4] |= S_008F20_DEPTH(depth - 1);
1181
 
      state[5] |= S_008F24_LAST_ARRAY(last_layer);
1182
 
   }
1183
 
   if (!(image->planes[0].surface.flags & RADEON_SURF_Z_OR_SBUFFER) &&
1184
 
       image->planes[0].surface.meta_offset) {
1185
 
      state[6] = S_008F28_ALPHA_IS_ON_MSB(vi_alpha_is_on_msb(device, vk_format));
1186
 
   } else {
1187
 
      if (device->instance->disable_aniso_single_level) {
1188
 
         /* The last dword is unused by hw. The shader uses it to clear
1189
 
          * bits in the first dword of sampler state.
1190
 
          */
1191
 
         if (device->physical_device->rad_info.chip_class <= GFX7 && image->info.samples <= 1) {
1192
 
            if (first_level == last_level)
1193
 
               state[7] = C_008F30_MAX_ANISO_RATIO;
1194
 
            else
1195
 
               state[7] = 0xffffffff;
1196
 
         }
1197
 
      }
1198
 
   }
1199
 
 
1200
 
   /* Initialize the sampler view for FMASK. */
1201
 
   if (fmask_state) {
1202
 
      if (radv_image_has_fmask(image)) {
1203
 
         uint32_t fmask_format;
1204
 
         uint64_t gpu_address = radv_buffer_get_va(image->bo);
1205
 
         uint64_t va;
1206
 
 
1207
 
         assert(image->plane_count == 1);
1208
 
 
1209
 
         va = gpu_address + image->offset + image->planes[0].surface.fmask_offset;
1210
 
 
1211
 
         if (device->physical_device->rad_info.chip_class == GFX9) {
1212
 
            fmask_format = V_008F14_IMG_DATA_FORMAT_FMASK;
1213
 
            switch (image->info.samples) {
1214
 
            case 2:
1215
 
               num_format = V_008F14_IMG_NUM_FORMAT_FMASK_8_2_2;
1216
 
               break;
1217
 
            case 4:
1218
 
               num_format = V_008F14_IMG_NUM_FORMAT_FMASK_8_4_4;
1219
 
               break;
1220
 
            case 8:
1221
 
               num_format = V_008F14_IMG_NUM_FORMAT_FMASK_32_8_8;
1222
 
               break;
1223
 
            default:
1224
 
               unreachable("invalid nr_samples");
1225
 
            }
1226
 
         } else {
1227
 
            switch (image->info.samples) {
1228
 
            case 2:
1229
 
               fmask_format = V_008F14_IMG_DATA_FORMAT_FMASK8_S2_F2;
1230
 
               break;
1231
 
            case 4:
1232
 
               fmask_format = V_008F14_IMG_DATA_FORMAT_FMASK8_S4_F4;
1233
 
               break;
1234
 
            case 8:
1235
 
               fmask_format = V_008F14_IMG_DATA_FORMAT_FMASK32_S8_F8;
1236
 
               break;
1237
 
            default:
1238
 
               assert(0);
1239
 
               fmask_format = V_008F14_IMG_DATA_FORMAT_INVALID;
1240
 
            }
1241
 
            num_format = V_008F14_IMG_NUM_FORMAT_UINT;
1242
 
         }
1243
 
 
1244
 
         fmask_state[0] = va >> 8;
1245
 
         fmask_state[0] |= image->planes[0].surface.fmask_tile_swizzle;
1246
 
         fmask_state[1] = S_008F14_BASE_ADDRESS_HI(va >> 40) | S_008F14_DATA_FORMAT(fmask_format) |
1247
 
                          S_008F14_NUM_FORMAT(num_format);
1248
 
         fmask_state[2] = S_008F18_WIDTH(width - 1) | S_008F18_HEIGHT(height - 1);
1249
 
         fmask_state[3] =
1250
 
            S_008F1C_DST_SEL_X(V_008F1C_SQ_SEL_X) | S_008F1C_DST_SEL_Y(V_008F1C_SQ_SEL_X) |
1251
 
            S_008F1C_DST_SEL_Z(V_008F1C_SQ_SEL_X) | S_008F1C_DST_SEL_W(V_008F1C_SQ_SEL_X) |
1252
 
            S_008F1C_TYPE(
1253
 
               radv_tex_dim(image->type, view_type, image->info.array_size, 0, false, false));
1254
 
         fmask_state[4] = 0;
1255
 
         fmask_state[5] = S_008F24_BASE_ARRAY(first_layer);
1256
 
         fmask_state[6] = 0;
1257
 
         fmask_state[7] = 0;
1258
 
 
1259
 
         if (device->physical_device->rad_info.chip_class == GFX9) {
1260
 
            fmask_state[3] |= S_008F1C_SW_MODE(image->planes[0].surface.u.gfx9.color.fmask_swizzle_mode);
1261
 
            fmask_state[4] |= S_008F20_DEPTH(last_layer) |
1262
 
                              S_008F20_PITCH(image->planes[0].surface.u.gfx9.color.fmask_epitch);
1263
 
            fmask_state[5] |= S_008F24_META_PIPE_ALIGNED(1) | S_008F24_META_RB_ALIGNED(1);
1264
 
 
1265
 
            if (radv_image_is_tc_compat_cmask(image)) {
1266
 
               va = gpu_address + image->offset + image->planes[0].surface.cmask_offset;
1267
 
 
1268
 
               fmask_state[5] |= S_008F24_META_DATA_ADDRESS(va >> 40);
1269
 
               fmask_state[6] |= S_008F28_COMPRESSION_EN(1);
1270
 
               fmask_state[7] |= va >> 8;
1271
 
            }
1272
 
         } else {
1273
 
            fmask_state[3] |=
1274
 
               S_008F1C_TILING_INDEX(image->planes[0].surface.u.legacy.color.fmask.tiling_index);
1275
 
            fmask_state[4] |=
1276
 
               S_008F20_DEPTH(depth - 1) |
1277
 
               S_008F20_PITCH(image->planes[0].surface.u.legacy.color.fmask.pitch_in_pixels - 1);
1278
 
            fmask_state[5] |= S_008F24_LAST_ARRAY(last_layer);
1279
 
 
1280
 
            if (radv_image_is_tc_compat_cmask(image)) {
1281
 
               va = gpu_address + image->offset + image->planes[0].surface.cmask_offset;
1282
 
 
1283
 
               fmask_state[6] |= S_008F28_COMPRESSION_EN(1);
1284
 
               fmask_state[7] |= va >> 8;
1285
 
            }
1286
 
         }
1287
 
      } else
1288
 
         memset(fmask_state, 0, 8 * 4);
1289
 
   }
1290
 
}
1291
 
 
1292
 
static void
1293
 
radv_make_texture_descriptor(struct radv_device *device, struct radv_image *image,
1294
 
                             bool is_storage_image, VkImageViewType view_type, VkFormat vk_format,
1295
 
                             const VkComponentMapping *mapping, unsigned first_level,
1296
 
                             unsigned last_level, unsigned first_layer, unsigned last_layer,
1297
 
                             unsigned width, unsigned height, unsigned depth, float min_lod, uint32_t *state,
1298
 
                             uint32_t *fmask_state)
1299
 
{
1300
 
   if (device->physical_device->rad_info.chip_class >= GFX10) {
1301
 
      gfx10_make_texture_descriptor(device, image, is_storage_image, view_type, vk_format, mapping,
1302
 
                                    first_level, last_level, first_layer, last_layer, width, height,
1303
 
                                    depth, min_lod, state, fmask_state);
1304
 
   } else {
1305
 
      si_make_texture_descriptor(device, image, is_storage_image, view_type, vk_format, mapping,
1306
 
                                 first_level, last_level, first_layer, last_layer, width, height,
1307
 
                                 depth, min_lod, state, fmask_state);
1308
 
   }
1309
 
}
1310
 
 
1311
 
static void
1312
 
radv_query_opaque_metadata(struct radv_device *device, struct radv_image *image,
1313
 
                           struct radeon_bo_metadata *md)
1314
 
{
1315
 
   static const VkComponentMapping fixedmapping;
1316
 
   uint32_t desc[8];
1317
 
 
1318
 
   assert(image->plane_count == 1);
1319
 
 
1320
 
   radv_make_texture_descriptor(device, image, false, (VkImageViewType)image->type,
1321
 
                                image->vk_format, &fixedmapping, 0, image->info.levels - 1, 0,
1322
 
                                image->info.array_size - 1, image->info.width, image->info.height,
1323
 
                                image->info.depth, 0.0f, desc, NULL);
1324
 
 
1325
 
   si_set_mutable_tex_desc_fields(device, image, &image->planes[0].surface.u.legacy.level[0], 0, 0,
1326
 
                                  0, image->planes[0].surface.blk_w, false, false, false, false,
1327
 
                                  desc);
1328
 
 
1329
 
   ac_surface_get_umd_metadata(&device->physical_device->rad_info, &image->planes[0].surface,
1330
 
                               image->info.levels, desc, &md->size_metadata, md->metadata);
1331
 
}
1332
 
 
1333
 
void
1334
 
radv_init_metadata(struct radv_device *device, struct radv_image *image,
1335
 
                   struct radeon_bo_metadata *metadata)
1336
 
{
1337
 
   struct radeon_surf *surface = &image->planes[0].surface;
1338
 
 
1339
 
   memset(metadata, 0, sizeof(*metadata));
1340
 
 
1341
 
   if (device->physical_device->rad_info.chip_class >= GFX9) {
1342
 
      uint64_t dcc_offset =
1343
 
         image->offset +
1344
 
         (surface->display_dcc_offset ? surface->display_dcc_offset : surface->meta_offset);
1345
 
      metadata->u.gfx9.swizzle_mode = surface->u.gfx9.swizzle_mode;
1346
 
      metadata->u.gfx9.dcc_offset_256b = dcc_offset >> 8;
1347
 
      metadata->u.gfx9.dcc_pitch_max = surface->u.gfx9.color.display_dcc_pitch_max;
1348
 
      metadata->u.gfx9.dcc_independent_64b_blocks = surface->u.gfx9.color.dcc.independent_64B_blocks;
1349
 
      metadata->u.gfx9.dcc_independent_128b_blocks = surface->u.gfx9.color.dcc.independent_128B_blocks;
1350
 
      metadata->u.gfx9.dcc_max_compressed_block_size =
1351
 
         surface->u.gfx9.color.dcc.max_compressed_block_size;
1352
 
      metadata->u.gfx9.scanout = (surface->flags & RADEON_SURF_SCANOUT) != 0;
1353
 
   } else {
1354
 
      metadata->u.legacy.microtile = surface->u.legacy.level[0].mode >= RADEON_SURF_MODE_1D
1355
 
                                        ? RADEON_LAYOUT_TILED
1356
 
                                        : RADEON_LAYOUT_LINEAR;
1357
 
      metadata->u.legacy.macrotile = surface->u.legacy.level[0].mode >= RADEON_SURF_MODE_2D
1358
 
                                        ? RADEON_LAYOUT_TILED
1359
 
                                        : RADEON_LAYOUT_LINEAR;
1360
 
      metadata->u.legacy.pipe_config = surface->u.legacy.pipe_config;
1361
 
      metadata->u.legacy.bankw = surface->u.legacy.bankw;
1362
 
      metadata->u.legacy.bankh = surface->u.legacy.bankh;
1363
 
      metadata->u.legacy.tile_split = surface->u.legacy.tile_split;
1364
 
      metadata->u.legacy.mtilea = surface->u.legacy.mtilea;
1365
 
      metadata->u.legacy.num_banks = surface->u.legacy.num_banks;
1366
 
      metadata->u.legacy.stride = surface->u.legacy.level[0].nblk_x * surface->bpe;
1367
 
      metadata->u.legacy.scanout = (surface->flags & RADEON_SURF_SCANOUT) != 0;
1368
 
   }
1369
 
   radv_query_opaque_metadata(device, image, metadata);
1370
 
}
1371
 
 
1372
 
void
1373
 
radv_image_override_offset_stride(struct radv_device *device, struct radv_image *image,
1374
 
                                  uint64_t offset, uint32_t stride)
1375
 
{
1376
 
   ac_surface_override_offset_stride(&device->physical_device->rad_info, &image->planes[0].surface,
1377
 
                                     image->info.levels, offset, stride);
1378
 
}
1379
 
 
1380
 
static void
1381
 
radv_image_alloc_single_sample_cmask(const struct radv_device *device,
1382
 
                                     const struct radv_image *image, struct radeon_surf *surf)
1383
 
{
1384
 
   if (!surf->cmask_size || surf->cmask_offset || surf->bpe > 8 || image->info.levels > 1 ||
1385
 
       image->info.depth > 1 || radv_image_has_dcc(image) ||
1386
 
       !radv_image_use_fast_clear_for_image(device, image) ||
1387
 
       (image->flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT))
1388
 
      return;
1389
 
 
1390
 
   assert(image->info.storage_samples == 1);
1391
 
 
1392
 
   surf->cmask_offset = align64(surf->total_size, 1 << surf->cmask_alignment_log2);
1393
 
   surf->total_size = surf->cmask_offset + surf->cmask_size;
1394
 
   surf->alignment_log2 = MAX2(surf->alignment_log2, surf->cmask_alignment_log2);
1395
 
}
1396
 
 
1397
 
static void
1398
 
radv_image_alloc_values(const struct radv_device *device, struct radv_image *image)
1399
 
{
1400
 
   /* images with modifiers can be potentially imported */
1401
 
   if (image->tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT)
1402
 
      return;
1403
 
 
1404
 
   if (radv_image_has_cmask(image) || (radv_image_has_dcc(image) && !image->support_comp_to_single)) {
1405
 
      image->fce_pred_offset = image->size;
1406
 
      image->size += 8 * image->info.levels;
1407
 
   }
1408
 
 
1409
 
   if (radv_image_use_dcc_predication(device, image)) {
1410
 
      image->dcc_pred_offset = image->size;
1411
 
      image->size += 8 * image->info.levels;
1412
 
   }
1413
 
 
1414
 
   if ((radv_image_has_dcc(image) && !image->support_comp_to_single) ||
1415
 
       radv_image_has_cmask(image) || radv_image_has_htile(image)) {
1416
 
      image->clear_value_offset = image->size;
1417
 
      image->size += 8 * image->info.levels;
1418
 
   }
1419
 
 
1420
 
   if (radv_image_is_tc_compat_htile(image) &&
1421
 
       device->physical_device->rad_info.has_tc_compat_zrange_bug) {
1422
 
      /* Metadata for the TC-compatible HTILE hardware bug which
1423
 
       * have to be fixed by updating ZRANGE_PRECISION when doing
1424
 
       * fast depth clears to 0.0f.
1425
 
       */
1426
 
      image->tc_compat_zrange_offset = image->size;
1427
 
      image->size += image->info.levels * 4;
1428
 
   }
1429
 
}
1430
 
 
1431
 
/* Determine if the image is affected by the pipe misaligned metadata issue
1432
 
 * which requires to invalidate L2.
1433
 
 */
1434
 
static bool
1435
 
radv_image_is_pipe_misaligned(const struct radv_device *device, const struct radv_image *image)
1436
 
{
1437
 
   struct radeon_info *rad_info = &device->physical_device->rad_info;
1438
 
   int log2_samples = util_logbase2(image->info.samples);
1439
 
 
1440
 
   assert(rad_info->chip_class >= GFX10);
1441
 
 
1442
 
   for (unsigned i = 0; i < image->plane_count; ++i) {
1443
 
      VkFormat fmt = radv_image_get_plane_format(device->physical_device, image, i);
1444
 
      int log2_bpp = util_logbase2(vk_format_get_blocksize(fmt));
1445
 
      int log2_bpp_and_samples;
1446
 
 
1447
 
      if (rad_info->chip_class >= GFX10_3) {
1448
 
         log2_bpp_and_samples = log2_bpp + log2_samples;
1449
 
      } else {
1450
 
         if (vk_format_has_depth(image->vk_format) && image->info.array_size >= 8) {
1451
 
            log2_bpp = 2;
1452
 
         }
1453
 
 
1454
 
         log2_bpp_and_samples = MIN2(6, log2_bpp + log2_samples);
1455
 
      }
1456
 
 
1457
 
      int num_pipes = G_0098F8_NUM_PIPES(rad_info->gb_addr_config);
1458
 
      int overlap = MAX2(0, log2_bpp_and_samples + num_pipes - 8);
1459
 
 
1460
 
      if (vk_format_has_depth(image->vk_format)) {
1461
 
         if (radv_image_is_tc_compat_htile(image) && overlap) {
1462
 
            return true;
1463
 
         }
1464
 
      } else {
1465
 
         int max_compressed_frags = G_0098F8_MAX_COMPRESSED_FRAGS(rad_info->gb_addr_config);
1466
 
         int log2_samples_frag_diff = MAX2(0, log2_samples - max_compressed_frags);
1467
 
         int samples_overlap = MIN2(log2_samples, overlap);
1468
 
 
1469
 
         /* TODO: It shouldn't be necessary if the image has DCC but
1470
 
          * not readable by shader.
1471
 
          */
1472
 
         if ((radv_image_has_dcc(image) || radv_image_is_tc_compat_cmask(image)) &&
1473
 
             (samples_overlap > log2_samples_frag_diff)) {
1474
 
            return true;
1475
 
         }
1476
 
      }
1477
 
   }
1478
 
 
1479
 
   return false;
1480
 
}
1481
 
 
1482
 
static bool
1483
 
radv_image_is_l2_coherent(const struct radv_device *device, const struct radv_image *image)
1484
 
{
1485
 
   if (device->physical_device->rad_info.chip_class >= GFX10) {
1486
 
      return !device->physical_device->rad_info.tcc_rb_non_coherent &&
1487
 
             !radv_image_is_pipe_misaligned(device, image);
1488
 
   } else if (device->physical_device->rad_info.chip_class == GFX9) {
1489
 
      if (image->info.samples == 1 &&
1490
 
          (image->usage &
1491
 
           (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)) &&
1492
 
          !vk_format_has_stencil(image->vk_format)) {
1493
 
         /* Single-sample color and single-sample depth
1494
 
          * (not stencil) are coherent with shaders on
1495
 
          * GFX9.
1496
 
          */
1497
 
         return true;
1498
 
      }
1499
 
   }
1500
 
 
1501
 
   return false;
1502
 
}
1503
 
 
1504
 
/**
1505
 
 * Determine if the given image can be fast cleared.
1506
 
 */
1507
 
static bool
1508
 
radv_image_can_fast_clear(const struct radv_device *device, const struct radv_image *image)
1509
 
{
1510
 
   if (device->instance->debug_flags & RADV_DEBUG_NO_FAST_CLEARS)
1511
 
      return false;
1512
 
 
1513
 
   if (vk_format_is_color(image->vk_format)) {
1514
 
      if (!radv_image_has_cmask(image) && !radv_image_has_dcc(image))
1515
 
         return false;
1516
 
 
1517
 
      /* RB+ doesn't work with CMASK fast clear on Stoney. */
1518
 
      if (!radv_image_has_dcc(image) && device->physical_device->rad_info.family == CHIP_STONEY)
1519
 
         return false;
1520
 
   } else {
1521
 
      if (!radv_image_has_htile(image))
1522
 
         return false;
1523
 
   }
1524
 
 
1525
 
   /* Do not fast clears 3D images. */
1526
 
   if (image->type == VK_IMAGE_TYPE_3D)
1527
 
      return false;
1528
 
 
1529
 
   return true;
1530
 
}
1531
 
 
1532
 
/**
1533
 
 * Determine if the given image can be fast cleared using comp-to-single.
1534
 
 */
1535
 
static bool
1536
 
radv_image_use_comp_to_single(const struct radv_device *device, const struct radv_image *image)
1537
 
{
1538
 
   /* comp-to-single is only available for GFX10+. */
1539
 
   if (device->physical_device->rad_info.chip_class < GFX10)
1540
 
      return false;
1541
 
 
1542
 
   /* If the image can't be fast cleared, comp-to-single can't be used. */
1543
 
   if (!radv_image_can_fast_clear(device, image))
1544
 
      return false;
1545
 
 
1546
 
   /* If the image doesn't have DCC, it can't be fast cleared using comp-to-single */
1547
 
   if (!radv_image_has_dcc(image))
1548
 
      return false;
1549
 
 
1550
 
   /* It seems 8bpp and 16bpp require RB+ to work. */
1551
 
   unsigned bytes_per_pixel = vk_format_get_blocksize(image->vk_format);
1552
 
   if (bytes_per_pixel <= 2 && !device->physical_device->rad_info.rbplus_allowed)
1553
 
      return false;
1554
 
 
1555
 
   return true;
1556
 
}
1557
 
 
1558
 
static unsigned
1559
 
radv_get_internal_plane_count(const struct radv_physical_device *pdev, VkFormat fmt)
1560
 
{
1561
 
   if (pdev->emulate_etc2 && vk_format_description(fmt)->layout == UTIL_FORMAT_LAYOUT_ETC)
1562
 
      return 2;
1563
 
   return vk_format_get_plane_count(fmt);
1564
 
}
1565
 
 
1566
 
static void
1567
 
radv_image_reset_layout(const struct radv_physical_device *pdev, struct radv_image *image)
1568
 
{
1569
 
   image->size = 0;
1570
 
   image->alignment = 1;
1571
 
 
1572
 
   image->tc_compatible_cmask = 0;
1573
 
   image->fce_pred_offset = image->dcc_pred_offset = 0;
1574
 
   image->clear_value_offset = image->tc_compat_zrange_offset = 0;
1575
 
 
1576
 
   unsigned plane_count = radv_get_internal_plane_count(pdev, image->vk_format);
1577
 
   for (unsigned i = 0; i < plane_count; ++i) {
1578
 
      VkFormat format = radv_image_get_plane_format(pdev, image, i);
1579
 
      if (vk_format_has_depth(format))
1580
 
         format = vk_format_depth_only(format);
1581
 
 
1582
 
      uint64_t flags = image->planes[i].surface.flags;
1583
 
      uint64_t modifier = image->planes[i].surface.modifier;
1584
 
      memset(image->planes + i, 0, sizeof(image->planes[i]));
1585
 
 
1586
 
      image->planes[i].surface.flags = flags;
1587
 
      image->planes[i].surface.modifier = modifier;
1588
 
      image->planes[i].surface.blk_w = vk_format_get_blockwidth(format);
1589
 
      image->planes[i].surface.blk_h = vk_format_get_blockheight(format);
1590
 
      image->planes[i].surface.bpe = vk_format_get_blocksize(format);
1591
 
 
1592
 
      /* align byte per element on dword */
1593
 
      if (image->planes[i].surface.bpe == 3) {
1594
 
         image->planes[i].surface.bpe = 4;
1595
 
      }
1596
 
   }
1597
 
}
1598
 
 
1599
 
VkResult
1600
 
radv_image_create_layout(struct radv_device *device, struct radv_image_create_info create_info,
1601
 
                         const struct VkImageDrmFormatModifierExplicitCreateInfoEXT *mod_info,
1602
 
                         struct radv_image *image)
1603
 
{
1604
 
   /* Clear the pCreateInfo pointer so we catch issues in the delayed case when we test in the
1605
 
    * common internal case. */
1606
 
   create_info.vk_info = NULL;
1607
 
 
1608
 
   struct ac_surf_info image_info = image->info;
1609
 
   VkResult result = radv_patch_image_from_extra_info(device, image, &create_info, &image_info);
1610
 
   if (result != VK_SUCCESS)
1611
 
      return result;
1612
 
 
1613
 
   assert(!mod_info || mod_info->drmFormatModifierPlaneCount >= image->plane_count);
1614
 
 
1615
 
   radv_image_reset_layout(device->physical_device, image);
1616
 
 
1617
 
   unsigned plane_count = radv_get_internal_plane_count(device->physical_device, image->vk_format);
1618
 
   for (unsigned plane = 0; plane < plane_count; ++plane) {
1619
 
      struct ac_surf_info info = image_info;
1620
 
      uint64_t offset;
1621
 
      unsigned stride;
1622
 
 
1623
 
      info.width = vk_format_get_plane_width(image->vk_format, plane, info.width);
1624
 
      info.height = vk_format_get_plane_height(image->vk_format, plane, info.height);
1625
 
 
1626
 
      if (create_info.no_metadata_planes || plane_count > 1) {
1627
 
         image->planes[plane].surface.flags |=
1628
 
            RADEON_SURF_DISABLE_DCC | RADEON_SURF_NO_FMASK | RADEON_SURF_NO_HTILE;
1629
 
      }
1630
 
 
1631
 
      device->ws->surface_init(device->ws, &info, &image->planes[plane].surface);
1632
 
 
1633
 
      if (plane == 0) {
1634
 
         if (!radv_use_dcc_for_image_late(device, image))
1635
 
            ac_surface_zero_dcc_fields(&image->planes[0].surface);
1636
 
      }
1637
 
 
1638
 
      if (create_info.bo_metadata && !mod_info &&
1639
 
          !ac_surface_set_umd_metadata(&device->physical_device->rad_info,
1640
 
                                       &image->planes[plane].surface, image_info.storage_samples,
1641
 
                                       image_info.levels, create_info.bo_metadata->size_metadata,
1642
 
                                       create_info.bo_metadata->metadata))
1643
 
         return VK_ERROR_INVALID_EXTERNAL_HANDLE;
1644
 
 
1645
 
      if (!create_info.no_metadata_planes && !create_info.bo_metadata && plane_count == 1 &&
1646
 
          !mod_info)
1647
 
         radv_image_alloc_single_sample_cmask(device, image, &image->planes[plane].surface);
1648
 
 
1649
 
      if (mod_info) {
1650
 
         if (mod_info->pPlaneLayouts[plane].rowPitch % image->planes[plane].surface.bpe ||
1651
 
             !mod_info->pPlaneLayouts[plane].rowPitch)
1652
 
            return VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT;
1653
 
 
1654
 
         offset = mod_info->pPlaneLayouts[plane].offset;
1655
 
         stride = mod_info->pPlaneLayouts[plane].rowPitch / image->planes[plane].surface.bpe;
1656
 
      } else {
1657
 
         offset = align64(image->size, 1 << image->planes[plane].surface.alignment_log2);
1658
 
         stride = 0; /* 0 means no override */
1659
 
      }
1660
 
 
1661
 
      if (!ac_surface_override_offset_stride(&device->physical_device->rad_info,
1662
 
                                             &image->planes[plane].surface, image->info.levels,
1663
 
                                             offset, stride))
1664
 
         return VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT;
1665
 
 
1666
 
      /* Validate DCC offsets in modifier layout. */
1667
 
      if (plane_count == 1 && mod_info) {
1668
 
         unsigned mem_planes = ac_surface_get_nplanes(&image->planes[plane].surface);
1669
 
         if (mod_info->drmFormatModifierPlaneCount != mem_planes)
1670
 
            return VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT;
1671
 
 
1672
 
         for (unsigned i = 1; i < mem_planes; ++i) {
1673
 
            if (ac_surface_get_plane_offset(device->physical_device->rad_info.chip_class,
1674
 
                                            &image->planes[plane].surface, i,
1675
 
                                            0) != mod_info->pPlaneLayouts[i].offset)
1676
 
               return VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT;
1677
 
         }
1678
 
      }
1679
 
 
1680
 
      image->size = MAX2(image->size, offset + image->planes[plane].surface.total_size);
1681
 
      image->alignment = MAX2(image->alignment, 1 << image->planes[plane].surface.alignment_log2);
1682
 
 
1683
 
      image->planes[plane].format =
1684
 
         radv_image_get_plane_format(device->physical_device, image, plane);
1685
 
   }
1686
 
 
1687
 
   image->tc_compatible_cmask =
1688
 
      radv_image_has_cmask(image) && radv_use_tc_compat_cmask_for_image(device, image);
1689
 
 
1690
 
   image->l2_coherent = radv_image_is_l2_coherent(device, image);
1691
 
 
1692
 
   image->support_comp_to_single = radv_image_use_comp_to_single(device, image);
1693
 
 
1694
 
   radv_image_alloc_values(device, image);
1695
 
 
1696
 
   assert(image->planes[0].surface.surf_size);
1697
 
   assert(image->planes[0].surface.modifier == DRM_FORMAT_MOD_INVALID ||
1698
 
          ac_modifier_has_dcc(image->planes[0].surface.modifier) == radv_image_has_dcc(image));
1699
 
   return VK_SUCCESS;
1700
 
}
1701
 
 
1702
 
static void
1703
 
radv_destroy_image(struct radv_device *device, const VkAllocationCallbacks *pAllocator,
1704
 
                   struct radv_image *image)
1705
 
{
1706
 
   if ((image->flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT) && image->bo)
1707
 
      device->ws->buffer_destroy(device->ws, image->bo);
1708
 
 
1709
 
   if (image->owned_memory != VK_NULL_HANDLE) {
1710
 
      RADV_FROM_HANDLE(radv_device_memory, mem, image->owned_memory);
1711
 
      radv_free_memory(device, pAllocator, mem);
1712
 
   }
1713
 
 
1714
 
   vk_object_base_finish(&image->base);
1715
 
   vk_free2(&device->vk.alloc, pAllocator, image);
1716
 
}
1717
 
 
1718
 
static void
1719
 
radv_image_print_info(struct radv_device *device, struct radv_image *image)
1720
 
{
1721
 
   fprintf(stderr, "Image:\n");
1722
 
   fprintf(stderr,
1723
 
           "  Info: size=%" PRIu64 ", alignment=%" PRIu32 ", "
1724
 
           "width=%" PRIu32 ", height=%" PRIu32 ", "
1725
 
           "offset=%" PRIu64 ", array_size=%" PRIu32 ", levels=%" PRIu32 "\n",
1726
 
           image->size, image->alignment, image->info.width, image->info.height, image->offset,
1727
 
           image->info.array_size, image->info.levels);
1728
 
   for (unsigned i = 0; i < image->plane_count; ++i) {
1729
 
      const struct radv_image_plane *plane = &image->planes[i];
1730
 
      const struct radeon_surf *surf = &plane->surface;
1731
 
      const struct util_format_description *desc = vk_format_description(plane->format);
1732
 
      uint64_t offset = ac_surface_get_plane_offset(device->physical_device->rad_info.chip_class,
1733
 
                                                    &plane->surface, 0, 0);
1734
 
 
1735
 
      fprintf(stderr, "  Plane[%u]: vkformat=%s, offset=%" PRIu64 "\n", i, desc->name, offset);
1736
 
 
1737
 
      ac_surface_print_info(stderr, &device->physical_device->rad_info, surf);
1738
 
   }
1739
 
}
1740
 
 
1741
 
static uint64_t
1742
 
radv_select_modifier(const struct radv_device *dev, VkFormat format,
1743
 
                     const struct VkImageDrmFormatModifierListCreateInfoEXT *mod_list)
1744
 
{
1745
 
   const struct radv_physical_device *pdev = dev->physical_device;
1746
 
   unsigned mod_count;
1747
 
 
1748
 
   assert(mod_list->drmFormatModifierCount);
1749
 
 
1750
 
   /* We can allow everything here as it does not affect order and the application
1751
 
    * is only allowed to specify modifiers that we support. */
1752
 
   const struct ac_modifier_options modifier_options = {
1753
 
      .dcc = true,
1754
 
      .dcc_retile = true,
1755
 
   };
1756
 
 
1757
 
   ac_get_supported_modifiers(&pdev->rad_info, &modifier_options, vk_format_to_pipe_format(format),
1758
 
                              &mod_count, NULL);
1759
 
 
1760
 
   uint64_t *mods = calloc(mod_count, sizeof(*mods));
1761
 
 
1762
 
   /* If allocations fail, fall back to a dumber solution. */
1763
 
   if (!mods)
1764
 
      return mod_list->pDrmFormatModifiers[0];
1765
 
 
1766
 
   ac_get_supported_modifiers(&pdev->rad_info, &modifier_options, vk_format_to_pipe_format(format),
1767
 
                              &mod_count, mods);
1768
 
 
1769
 
   for (unsigned i = 0; i < mod_count; ++i) {
1770
 
      for (uint32_t j = 0; j < mod_list->drmFormatModifierCount; ++j) {
1771
 
         if (mods[i] == mod_list->pDrmFormatModifiers[j]) {
1772
 
            free(mods);
1773
 
            return mod_list->pDrmFormatModifiers[j];
1774
 
         }
1775
 
      }
1776
 
   }
1777
 
   unreachable("App specified an invalid modifier");
1778
 
}
1779
 
 
1780
 
VkResult
1781
 
radv_image_create(VkDevice _device, const struct radv_image_create_info *create_info,
1782
 
                  const VkAllocationCallbacks *alloc, VkImage *pImage)
1783
 
{
1784
 
   RADV_FROM_HANDLE(radv_device, device, _device);
1785
 
   const VkImageCreateInfo *pCreateInfo = create_info->vk_info;
1786
 
   uint64_t modifier = DRM_FORMAT_MOD_INVALID;
1787
 
   struct radv_image *image = NULL;
1788
 
   VkFormat format = radv_select_android_external_format(pCreateInfo->pNext, pCreateInfo->format);
1789
 
   const struct VkImageDrmFormatModifierListCreateInfoEXT *mod_list =
1790
 
      vk_find_struct_const(pCreateInfo->pNext, IMAGE_DRM_FORMAT_MODIFIER_LIST_CREATE_INFO_EXT);
1791
 
   const struct VkImageDrmFormatModifierExplicitCreateInfoEXT *explicit_mod =
1792
 
      vk_find_struct_const(pCreateInfo->pNext, IMAGE_DRM_FORMAT_MODIFIER_EXPLICIT_CREATE_INFO_EXT);
1793
 
   assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO);
1794
 
 
1795
 
   unsigned plane_count = radv_get_internal_plane_count(device->physical_device, format);
1796
 
 
1797
 
   const size_t image_struct_size = sizeof(*image) + sizeof(struct radv_image_plane) * plane_count;
1798
 
 
1799
 
   radv_assert(pCreateInfo->mipLevels > 0);
1800
 
   radv_assert(pCreateInfo->arrayLayers > 0);
1801
 
   radv_assert(pCreateInfo->samples > 0);
1802
 
   radv_assert(pCreateInfo->extent.width > 0);
1803
 
   radv_assert(pCreateInfo->extent.height > 0);
1804
 
   radv_assert(pCreateInfo->extent.depth > 0);
1805
 
 
1806
 
   image =
1807
 
      vk_zalloc2(&device->vk.alloc, alloc, image_struct_size, 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
1808
 
   if (!image)
1809
 
      return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
1810
 
 
1811
 
   vk_object_base_init(&device->vk, &image->base, VK_OBJECT_TYPE_IMAGE);
1812
 
 
1813
 
   image->type = pCreateInfo->imageType;
1814
 
   image->info.width = pCreateInfo->extent.width;
1815
 
   image->info.height = pCreateInfo->extent.height;
1816
 
   image->info.depth = pCreateInfo->extent.depth;
1817
 
   image->info.samples = pCreateInfo->samples;
1818
 
   image->info.storage_samples = pCreateInfo->samples;
1819
 
   image->info.array_size = pCreateInfo->arrayLayers;
1820
 
   image->info.levels = pCreateInfo->mipLevels;
1821
 
   image->info.num_channels = vk_format_get_nr_components(format);
1822
 
 
1823
 
   image->vk_format = format;
1824
 
   image->tiling = pCreateInfo->tiling;
1825
 
   image->usage = pCreateInfo->usage;
1826
 
   image->flags = pCreateInfo->flags;
1827
 
   image->plane_count = vk_format_get_plane_count(format);
1828
 
 
1829
 
   image->exclusive = pCreateInfo->sharingMode == VK_SHARING_MODE_EXCLUSIVE;
1830
 
   if (pCreateInfo->sharingMode == VK_SHARING_MODE_CONCURRENT) {
1831
 
      for (uint32_t i = 0; i < pCreateInfo->queueFamilyIndexCount; ++i)
1832
 
         if (pCreateInfo->pQueueFamilyIndices[i] == VK_QUEUE_FAMILY_EXTERNAL ||
1833
 
             pCreateInfo->pQueueFamilyIndices[i] == VK_QUEUE_FAMILY_FOREIGN_EXT)
1834
 
            image->queue_family_mask |= (1u << RADV_MAX_QUEUE_FAMILIES) - 1u;
1835
 
         else
1836
 
            image->queue_family_mask |= 1u << vk_queue_to_radv(device->physical_device,
1837
 
                                                               pCreateInfo->pQueueFamilyIndices[i]);
1838
 
   }
1839
 
 
1840
 
   const VkExternalMemoryImageCreateInfo *external_info =
1841
 
      vk_find_struct_const(pCreateInfo->pNext, EXTERNAL_MEMORY_IMAGE_CREATE_INFO);
1842
 
 
1843
 
   image->shareable = external_info;
1844
 
   if (!vk_format_is_depth_or_stencil(format) && !image->shareable &&
1845
 
       !(image->flags & VK_IMAGE_CREATE_SPARSE_ALIASED_BIT) &&
1846
 
       pCreateInfo->tiling != VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT) {
1847
 
      image->info.surf_index = &device->image_mrt_offset_counter;
1848
 
   }
1849
 
 
1850
 
   if (mod_list)
1851
 
      modifier = radv_select_modifier(device, format, mod_list);
1852
 
   else if (explicit_mod)
1853
 
      modifier = explicit_mod->drmFormatModifier;
1854
 
 
1855
 
   for (unsigned plane = 0; plane < plane_count; ++plane) {
1856
 
      image->planes[plane].surface.flags =
1857
 
         radv_get_surface_flags(device, image, plane, pCreateInfo, format);
1858
 
      image->planes[plane].surface.modifier = modifier;
1859
 
   }
1860
 
 
1861
 
   bool delay_layout =
1862
 
      external_info && (external_info->handleTypes &
1863
 
                        VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID);
1864
 
 
1865
 
   if (delay_layout) {
1866
 
      *pImage = radv_image_to_handle(image);
1867
 
      assert(!(image->flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT));
1868
 
      return VK_SUCCESS;
1869
 
   }
1870
 
 
1871
 
   VkResult result = radv_image_create_layout(device, *create_info, explicit_mod, image);
1872
 
   if (result != VK_SUCCESS) {
1873
 
      radv_destroy_image(device, alloc, image);
1874
 
      return result;
1875
 
   }
1876
 
 
1877
 
   if (image->flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT) {
1878
 
      image->alignment = MAX2(image->alignment, 4096);
1879
 
      image->size = align64(image->size, image->alignment);
1880
 
      image->offset = 0;
1881
 
 
1882
 
      result =
1883
 
         device->ws->buffer_create(device->ws, image->size, image->alignment, 0,
1884
 
                                   RADEON_FLAG_VIRTUAL, RADV_BO_PRIORITY_VIRTUAL, 0, &image->bo);
1885
 
      if (result != VK_SUCCESS) {
1886
 
         radv_destroy_image(device, alloc, image);
1887
 
         return vk_error(device, result);
1888
 
      }
1889
 
   }
1890
 
 
1891
 
   if (device->instance->debug_flags & RADV_DEBUG_IMG) {
1892
 
      radv_image_print_info(device, image);
1893
 
   }
1894
 
 
1895
 
   *pImage = radv_image_to_handle(image);
1896
 
 
1897
 
   return VK_SUCCESS;
1898
 
}
1899
 
 
1900
 
static void
1901
 
radv_image_view_make_descriptor(struct radv_image_view *iview, struct radv_device *device,
1902
 
                                VkFormat vk_format, const VkComponentMapping *components,
1903
 
                                float min_lod,
1904
 
                                bool is_storage_image, bool disable_compression,
1905
 
                                bool enable_compression, unsigned plane_id,
1906
 
                                unsigned descriptor_plane_id)
1907
 
{
1908
 
   struct radv_image *image = iview->image;
1909
 
   struct radv_image_plane *plane = &image->planes[plane_id];
1910
 
   bool is_stencil = iview->aspect_mask == VK_IMAGE_ASPECT_STENCIL_BIT;
1911
 
   uint32_t blk_w;
1912
 
   union radv_descriptor *descriptor;
1913
 
   uint32_t hw_level = 0;
1914
 
 
1915
 
   if (is_storage_image) {
1916
 
      descriptor = &iview->storage_descriptor;
1917
 
   } else {
1918
 
      descriptor = &iview->descriptor;
1919
 
   }
1920
 
 
1921
 
   assert(vk_format_get_plane_count(vk_format) == 1);
1922
 
   assert(plane->surface.blk_w % vk_format_get_blockwidth(plane->format) == 0);
1923
 
   blk_w = plane->surface.blk_w / vk_format_get_blockwidth(plane->format) *
1924
 
           vk_format_get_blockwidth(vk_format);
1925
 
 
1926
 
   if (device->physical_device->rad_info.chip_class >= GFX9)
1927
 
      hw_level = iview->base_mip;
1928
 
   radv_make_texture_descriptor(
1929
 
      device, image, is_storage_image, iview->type, vk_format, components, hw_level,
1930
 
      hw_level + iview->level_count - 1, iview->base_layer,
1931
 
      iview->base_layer + iview->layer_count - 1,
1932
 
      vk_format_get_plane_width(image->vk_format, plane_id, iview->extent.width),
1933
 
      vk_format_get_plane_height(image->vk_format, plane_id, iview->extent.height),
1934
 
      iview->extent.depth, min_lod, descriptor->plane_descriptors[descriptor_plane_id],
1935
 
      descriptor_plane_id || is_storage_image ? NULL : descriptor->fmask_descriptor);
1936
 
 
1937
 
   const struct legacy_surf_level *base_level_info = NULL;
1938
 
   if (device->physical_device->rad_info.chip_class <= GFX9) {
1939
 
      if (is_stencil)
1940
 
         base_level_info = &plane->surface.u.legacy.zs.stencil_level[iview->base_mip];
1941
 
      else
1942
 
         base_level_info = &plane->surface.u.legacy.level[iview->base_mip];
1943
 
   }
1944
 
 
1945
 
   bool enable_write_compression = radv_image_use_dcc_image_stores(device, image);
1946
 
   if (is_storage_image && !(enable_write_compression || enable_compression))
1947
 
      disable_compression = true;
1948
 
   si_set_mutable_tex_desc_fields(device, image, base_level_info, plane_id, iview->base_mip,
1949
 
                                  iview->base_mip, blk_w, is_stencil, is_storage_image,
1950
 
                                  disable_compression, enable_write_compression,
1951
 
                                  descriptor->plane_descriptors[descriptor_plane_id]);
1952
 
}
1953
 
 
1954
 
static unsigned
1955
 
radv_plane_from_aspect(VkImageAspectFlags mask)
1956
 
{
1957
 
   switch (mask) {
1958
 
   case VK_IMAGE_ASPECT_PLANE_1_BIT:
1959
 
   case VK_IMAGE_ASPECT_MEMORY_PLANE_1_BIT_EXT:
1960
 
      return 1;
1961
 
   case VK_IMAGE_ASPECT_PLANE_2_BIT:
1962
 
   case VK_IMAGE_ASPECT_MEMORY_PLANE_2_BIT_EXT:
1963
 
      return 2;
1964
 
   case VK_IMAGE_ASPECT_MEMORY_PLANE_3_BIT_EXT:
1965
 
      return 3;
1966
 
   default:
1967
 
      return 0;
1968
 
   }
1969
 
}
1970
 
 
1971
 
VkFormat
1972
 
radv_get_aspect_format(struct radv_image *image, VkImageAspectFlags mask)
1973
 
{
1974
 
   switch (mask) {
1975
 
   case VK_IMAGE_ASPECT_PLANE_0_BIT:
1976
 
      return image->planes[0].format;
1977
 
   case VK_IMAGE_ASPECT_PLANE_1_BIT:
1978
 
      return image->planes[1].format;
1979
 
   case VK_IMAGE_ASPECT_PLANE_2_BIT:
1980
 
      return image->planes[2].format;
1981
 
   case VK_IMAGE_ASPECT_STENCIL_BIT:
1982
 
      return vk_format_stencil_only(image->vk_format);
1983
 
   case VK_IMAGE_ASPECT_DEPTH_BIT:
1984
 
      return vk_format_depth_only(image->vk_format);
1985
 
   case VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT:
1986
 
      return vk_format_depth_only(image->vk_format);
1987
 
   default:
1988
 
      return image->vk_format;
1989
 
   }
1990
 
}
1991
 
 
1992
 
/**
1993
 
 * Determine if the given image view can be fast cleared.
1994
 
 */
1995
 
static bool
1996
 
radv_image_view_can_fast_clear(const struct radv_device *device,
1997
 
                               const struct radv_image_view *iview)
1998
 
{
1999
 
   struct radv_image *image;
2000
 
 
2001
 
   if (!iview)
2002
 
      return false;
2003
 
   image = iview->image;
2004
 
 
2005
 
   /* Only fast clear if the image itself can be fast cleared. */
2006
 
   if (!radv_image_can_fast_clear(device, image))
2007
 
      return false;
2008
 
 
2009
 
   /* Only fast clear if all layers are bound. */
2010
 
   if (iview->base_layer > 0 || iview->layer_count != image->info.array_size)
2011
 
      return false;
2012
 
 
2013
 
   /* Only fast clear if the view covers the whole image. */
2014
 
   if (!radv_image_extent_compare(image, &iview->extent))
2015
 
      return false;
2016
 
 
2017
 
   return true;
2018
 
}
2019
 
 
2020
 
void
2021
 
radv_image_view_init(struct radv_image_view *iview, struct radv_device *device,
2022
 
                     const VkImageViewCreateInfo *pCreateInfo,
2023
 
                     const struct radv_image_view_extra_create_info *extra_create_info)
2024
 
{
2025
 
   RADV_FROM_HANDLE(radv_image, image, pCreateInfo->image);
2026
 
   const VkImageSubresourceRange *range = &pCreateInfo->subresourceRange;
2027
 
   uint32_t plane_count = 1;
2028
 
   float min_lod = 0.0f;
2029
 
 
2030
 
   const struct VkImageViewMinLodCreateInfoEXT *min_lod_info =
2031
 
      vk_find_struct_const(pCreateInfo->pNext, IMAGE_VIEW_MIN_LOD_CREATE_INFO_EXT);
2032
 
 
2033
 
   if (min_lod_info)
2034
 
      min_lod = min_lod_info->minLod;
2035
 
 
2036
 
   vk_object_base_init(&device->vk, &iview->base, VK_OBJECT_TYPE_IMAGE_VIEW);
2037
 
 
2038
 
   switch (image->type) {
2039
 
   case VK_IMAGE_TYPE_1D:
2040
 
   case VK_IMAGE_TYPE_2D:
2041
 
      assert(range->baseArrayLayer + radv_get_layerCount(image, range) - 1 <=
2042
 
             image->info.array_size);
2043
 
      break;
2044
 
   case VK_IMAGE_TYPE_3D:
2045
 
      assert(range->baseArrayLayer + radv_get_layerCount(image, range) - 1 <=
2046
 
             radv_minify(image->info.depth, range->baseMipLevel));
2047
 
      break;
2048
 
   default:
2049
 
      unreachable("bad VkImageType");
2050
 
   }
2051
 
   iview->image = image;
2052
 
   iview->type = pCreateInfo->viewType;
2053
 
   iview->plane_id = radv_plane_from_aspect(pCreateInfo->subresourceRange.aspectMask);
2054
 
   iview->aspect_mask = pCreateInfo->subresourceRange.aspectMask;
2055
 
   iview->base_layer = range->baseArrayLayer;
2056
 
   iview->layer_count = radv_get_layerCount(image, range);
2057
 
   iview->base_mip = range->baseMipLevel;
2058
 
   iview->level_count = radv_get_levelCount(image, range);
2059
 
 
2060
 
   iview->vk_format = pCreateInfo->format;
2061
 
 
2062
 
   /* If the image has an Android external format, pCreateInfo->format will be
2063
 
    * VK_FORMAT_UNDEFINED. */
2064
 
   if (iview->vk_format == VK_FORMAT_UNDEFINED)
2065
 
      iview->vk_format = image->vk_format;
2066
 
 
2067
 
   /* Split out the right aspect. Note that for internal meta code we sometimes
2068
 
    * use an equivalent color format for the aspect so we first have to check
2069
 
    * if we actually got depth/stencil formats. */
2070
 
   if (iview->aspect_mask == VK_IMAGE_ASPECT_STENCIL_BIT) {
2071
 
      if (vk_format_has_stencil(iview->vk_format))
2072
 
         iview->vk_format = vk_format_stencil_only(iview->vk_format);
2073
 
   } else if (iview->aspect_mask == VK_IMAGE_ASPECT_DEPTH_BIT) {
2074
 
      if (vk_format_has_depth(iview->vk_format))
2075
 
         iview->vk_format = vk_format_depth_only(iview->vk_format);
2076
 
   }
2077
 
 
2078
 
   if (vk_format_get_plane_count(image->vk_format) > 1 &&
2079
 
       iview->aspect_mask == VK_IMAGE_ASPECT_COLOR_BIT) {
2080
 
      plane_count = vk_format_get_plane_count(iview->vk_format);
2081
 
   }
2082
 
 
2083
 
   if (device->physical_device->emulate_etc2 &&
2084
 
       vk_format_description(image->vk_format)->layout == UTIL_FORMAT_LAYOUT_ETC) {
2085
 
      const struct util_format_description *desc = vk_format_description(iview->vk_format);
2086
 
      assert(desc);
2087
 
      if (desc->layout == UTIL_FORMAT_LAYOUT_ETC) {
2088
 
         iview->plane_id = 1;
2089
 
         iview->vk_format = etc2_emulation_format(iview->vk_format);
2090
 
      }
2091
 
 
2092
 
      plane_count = 1;
2093
 
   }
2094
 
 
2095
 
   if (device->physical_device->rad_info.chip_class >= GFX9) {
2096
 
      iview->extent = (VkExtent3D){
2097
 
         .width = image->info.width,
2098
 
         .height = image->info.height,
2099
 
         .depth = image->info.depth,
2100
 
      };
2101
 
   } else {
2102
 
      iview->extent = (VkExtent3D){
2103
 
         .width = radv_minify(image->info.width, range->baseMipLevel),
2104
 
         .height = radv_minify(image->info.height, range->baseMipLevel),
2105
 
         .depth = radv_minify(image->info.depth, range->baseMipLevel),
2106
 
      };
2107
 
   }
2108
 
 
2109
 
   if (iview->vk_format != image->planes[iview->plane_id].format) {
2110
 
      unsigned view_bw = vk_format_get_blockwidth(iview->vk_format);
2111
 
      unsigned view_bh = vk_format_get_blockheight(iview->vk_format);
2112
 
      unsigned img_bw = vk_format_get_blockwidth(image->planes[iview->plane_id].format);
2113
 
      unsigned img_bh = vk_format_get_blockheight(image->planes[iview->plane_id].format);
2114
 
 
2115
 
      iview->extent.width = round_up_u32(iview->extent.width * view_bw, img_bw);
2116
 
      iview->extent.height = round_up_u32(iview->extent.height * view_bh, img_bh);
2117
 
 
2118
 
      /* Comment ported from amdvlk -
2119
 
       * If we have the following image:
2120
 
       *              Uncompressed pixels   Compressed block sizes (4x4)
2121
 
       *      mip0:       22 x 22                   6 x 6
2122
 
       *      mip1:       11 x 11                   3 x 3
2123
 
       *      mip2:        5 x  5                   2 x 2
2124
 
       *      mip3:        2 x  2                   1 x 1
2125
 
       *      mip4:        1 x  1                   1 x 1
2126
 
       *
2127
 
       * On GFX9 the descriptor is always programmed with the WIDTH and HEIGHT of the base level and
2128
 
       * the HW is calculating the degradation of the block sizes down the mip-chain as follows
2129
 
       * (straight-up divide-by-two integer math): mip0:  6x6 mip1:  3x3 mip2:  1x1 mip3:  1x1
2130
 
       *
2131
 
       * This means that mip2 will be missing texels.
2132
 
       *
2133
 
       * Fix this by calculating the base mip's width and height, then convert
2134
 
       * that, and round it back up to get the level 0 size. Clamp the
2135
 
       * converted size between the original values, and the physical extent
2136
 
       * of the base mipmap.
2137
 
       *
2138
 
       * On GFX10 we have to take care to not go over the physical extent
2139
 
       * of the base mipmap as otherwise the GPU computes a different layout.
2140
 
       * Note that the GPU does use the same base-mip dimensions for both a
2141
 
       * block compatible format and the compressed format, so even if we take
2142
 
       * the plain converted dimensions the physical layout is correct.
2143
 
       */
2144
 
      if (device->physical_device->rad_info.chip_class >= GFX9 &&
2145
 
          vk_format_is_compressed(image->vk_format) && !vk_format_is_compressed(iview->vk_format)) {
2146
 
         /* If we have multiple levels in the view we should ideally take the last level,
2147
 
          * but the mip calculation has a max(..., 1) so walking back to the base mip in an
2148
 
          * useful way is hard. */
2149
 
         if (iview->level_count > 1) {
2150
 
            iview->extent.width = iview->image->planes[0].surface.u.gfx9.base_mip_width;
2151
 
            iview->extent.height = iview->image->planes[0].surface.u.gfx9.base_mip_height;
2152
 
         } else {
2153
 
            unsigned lvl_width = radv_minify(image->info.width, range->baseMipLevel);
2154
 
            unsigned lvl_height = radv_minify(image->info.height, range->baseMipLevel);
2155
 
 
2156
 
            lvl_width = round_up_u32(lvl_width * view_bw, img_bw);
2157
 
            lvl_height = round_up_u32(lvl_height * view_bh, img_bh);
2158
 
 
2159
 
            lvl_width <<= range->baseMipLevel;
2160
 
            lvl_height <<= range->baseMipLevel;
2161
 
 
2162
 
            iview->extent.width = CLAMP(lvl_width, iview->extent.width,
2163
 
                                        iview->image->planes[0].surface.u.gfx9.base_mip_width);
2164
 
            iview->extent.height = CLAMP(lvl_height, iview->extent.height,
2165
 
                                         iview->image->planes[0].surface.u.gfx9.base_mip_height);
2166
 
         }
2167
 
      }
2168
 
   }
2169
 
 
2170
 
   iview->support_fast_clear = radv_image_view_can_fast_clear(device, iview);
2171
 
   iview->disable_dcc_mrt = extra_create_info ? extra_create_info->disable_dcc_mrt : false;
2172
 
 
2173
 
   bool disable_compression = extra_create_info ? extra_create_info->disable_compression : false;
2174
 
   bool enable_compression = extra_create_info ? extra_create_info->enable_compression : false;
2175
 
   for (unsigned i = 0; i < plane_count; ++i) {
2176
 
      VkFormat format = vk_format_get_plane_format(iview->vk_format, i);
2177
 
      radv_image_view_make_descriptor(iview, device, format, &pCreateInfo->components, min_lod, false,
2178
 
                                      disable_compression, enable_compression, iview->plane_id + i,
2179
 
                                      i);
2180
 
      radv_image_view_make_descriptor(iview, device, format, &pCreateInfo->components, min_lod, true,
2181
 
                                      disable_compression, enable_compression, iview->plane_id + i,
2182
 
                                      i);
2183
 
   }
2184
 
}
2185
 
 
2186
 
void
2187
 
radv_image_view_finish(struct radv_image_view *iview)
2188
 
{
2189
 
   vk_object_base_finish(&iview->base);
2190
 
}
2191
 
 
2192
 
bool
2193
 
radv_layout_is_htile_compressed(const struct radv_device *device, const struct radv_image *image,
2194
 
                                VkImageLayout layout, bool in_render_loop, unsigned queue_mask)
2195
 
{
2196
 
   switch (layout) {
2197
 
   case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
2198
 
   case VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL:
2199
 
   case VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL:
2200
 
   case VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL:
2201
 
      return radv_image_has_htile(image);
2202
 
   case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
2203
 
      return radv_image_is_tc_compat_htile(image) ||
2204
 
             (radv_image_has_htile(image) && queue_mask == (1u << RADV_QUEUE_GENERAL));
2205
 
   case VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR:
2206
 
   case VK_IMAGE_LAYOUT_GENERAL:
2207
 
      /* It should be safe to enable TC-compat HTILE with
2208
 
       * VK_IMAGE_LAYOUT_GENERAL if we are not in a render loop and
2209
 
       * if the image doesn't have the storage bit set. This
2210
 
       * improves performance for apps that use GENERAL for the main
2211
 
       * depth pass because this allows compression and this reduces
2212
 
       * the number of decompressions from/to GENERAL.
2213
 
       */
2214
 
      /* FIXME: Enabling TC-compat HTILE in GENERAL on the compute
2215
 
       * queue is likely broken for eg. depth/stencil copies.
2216
 
       */
2217
 
      if (radv_image_is_tc_compat_htile(image) && queue_mask & (1u << RADV_QUEUE_GENERAL) &&
2218
 
          !in_render_loop && !device->instance->disable_tc_compat_htile_in_general) {
2219
 
         return true;
2220
 
      } else {
2221
 
         return false;
2222
 
      }
2223
 
   case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL:
2224
 
      if (radv_image_is_tc_compat_htile(image) ||
2225
 
          (radv_image_has_htile(image) &&
2226
 
           !(image->usage & (VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)))) {
2227
 
         /* Keep HTILE compressed if the image is only going to
2228
 
          * be used as a depth/stencil read-only attachment.
2229
 
          */
2230
 
         return true;
2231
 
      } else {
2232
 
         return false;
2233
 
      }
2234
 
      break;
2235
 
   default:
2236
 
      return radv_image_is_tc_compat_htile(image);
2237
 
   }
2238
 
}
2239
 
 
2240
 
bool
2241
 
radv_layout_can_fast_clear(const struct radv_device *device, const struct radv_image *image,
2242
 
                           unsigned level, VkImageLayout layout, bool in_render_loop,
2243
 
                           unsigned queue_mask)
2244
 
{
2245
 
   if (radv_dcc_enabled(image, level) &&
2246
 
       !radv_layout_dcc_compressed(device, image, level, layout, in_render_loop, queue_mask))
2247
 
      return false;
2248
 
 
2249
 
   if (!(image->usage & RADV_IMAGE_USAGE_WRITE_BITS))
2250
 
      return false;
2251
 
 
2252
 
   if (layout != VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL &&
2253
 
       layout != VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL)
2254
 
      return false;
2255
 
 
2256
 
   /* Exclusive images with CMASK or DCC can always be fast-cleared on the gfx queue. Concurrent
2257
 
    * images can only be fast-cleared if comp-to-single is supported because we don't yet support
2258
 
    * FCE on the compute queue.
2259
 
    */
2260
 
   return queue_mask == (1u << RADV_QUEUE_GENERAL) || radv_image_use_comp_to_single(device, image);
2261
 
}
2262
 
 
2263
 
bool
2264
 
radv_layout_dcc_compressed(const struct radv_device *device, const struct radv_image *image,
2265
 
                           unsigned level, VkImageLayout layout, bool in_render_loop,
2266
 
                           unsigned queue_mask)
2267
 
{
2268
 
   if (!radv_dcc_enabled(image, level))
2269
 
      return false;
2270
 
 
2271
 
   if (image->tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT && queue_mask & (1u << RADV_QUEUE_FOREIGN))
2272
 
      return true;
2273
 
 
2274
 
   /* If the image is read-only, we can always just keep it compressed */
2275
 
   if (!(image->usage & RADV_IMAGE_USAGE_WRITE_BITS))
2276
 
      return true;
2277
 
 
2278
 
   /* Don't compress compute transfer dst when image stores are not supported. */
2279
 
   if ((layout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL || layout == VK_IMAGE_LAYOUT_GENERAL) &&
2280
 
       (queue_mask & (1u << RADV_QUEUE_COMPUTE)) && !radv_image_use_dcc_image_stores(device, image))
2281
 
      return false;
2282
 
 
2283
 
   return device->physical_device->rad_info.chip_class >= GFX10 || layout != VK_IMAGE_LAYOUT_GENERAL;
2284
 
}
2285
 
 
2286
 
bool
2287
 
radv_layout_fmask_compressed(const struct radv_device *device, const struct radv_image *image,
2288
 
                             VkImageLayout layout, unsigned queue_mask)
2289
 
{
2290
 
   if (!radv_image_has_fmask(image))
2291
 
      return false;
2292
 
 
2293
 
   /* Don't compress compute transfer dst because image stores ignore FMASK and it needs to be
2294
 
    * expanded before.
2295
 
    */
2296
 
   if ((layout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL || layout == VK_IMAGE_LAYOUT_GENERAL) &&
2297
 
       (queue_mask & (1u << RADV_QUEUE_COMPUTE)))
2298
 
      return false;
2299
 
 
2300
 
   /* Only compress concurrent images if TC-compat CMASK is enabled (no FMASK decompression). */
2301
 
   return layout != VK_IMAGE_LAYOUT_GENERAL &&
2302
 
          (queue_mask == (1u << RADV_QUEUE_GENERAL) || radv_image_is_tc_compat_cmask(image));
2303
 
}
2304
 
 
2305
 
unsigned
2306
 
radv_image_queue_family_mask(const struct radv_image *image,
2307
 
                             enum radv_queue_family family,
2308
 
                             enum radv_queue_family queue_family)
2309
 
{
2310
 
   if (!image->exclusive)
2311
 
      return image->queue_family_mask;
2312
 
   if (family == RADV_QUEUE_FOREIGN)
2313
 
      return ((1u << RADV_MAX_QUEUE_FAMILIES) - 1u) | (1u << RADV_QUEUE_FOREIGN);
2314
 
   if (family == RADV_QUEUE_IGNORED)
2315
 
      return 1u << queue_family;
2316
 
   return 1u << family;
2317
 
}
2318
 
 
2319
 
VKAPI_ATTR VkResult VKAPI_CALL
2320
 
radv_CreateImage(VkDevice device, const VkImageCreateInfo *pCreateInfo,
2321
 
                 const VkAllocationCallbacks *pAllocator, VkImage *pImage)
2322
 
{
2323
 
#ifdef ANDROID
2324
 
   const VkNativeBufferANDROID *gralloc_info =
2325
 
      vk_find_struct_const(pCreateInfo->pNext, NATIVE_BUFFER_ANDROID);
2326
 
 
2327
 
   if (gralloc_info)
2328
 
      return radv_image_from_gralloc(device, pCreateInfo, gralloc_info, pAllocator, pImage);
2329
 
#endif
2330
 
 
2331
 
   const struct wsi_image_create_info *wsi_info =
2332
 
      vk_find_struct_const(pCreateInfo->pNext, WSI_IMAGE_CREATE_INFO_MESA);
2333
 
   bool scanout = wsi_info && wsi_info->scanout;
2334
 
   bool prime_blit_src = wsi_info && wsi_info->buffer_blit_src;
2335
 
 
2336
 
   return radv_image_create(device,
2337
 
                            &(struct radv_image_create_info){
2338
 
                               .vk_info = pCreateInfo,
2339
 
                               .scanout = scanout,
2340
 
                               .prime_blit_src = prime_blit_src,
2341
 
                            },
2342
 
                            pAllocator, pImage);
2343
 
}
2344
 
 
2345
 
VKAPI_ATTR void VKAPI_CALL
2346
 
radv_DestroyImage(VkDevice _device, VkImage _image, const VkAllocationCallbacks *pAllocator)
2347
 
{
2348
 
   RADV_FROM_HANDLE(radv_device, device, _device);
2349
 
   RADV_FROM_HANDLE(radv_image, image, _image);
2350
 
 
2351
 
   if (!image)
2352
 
      return;
2353
 
 
2354
 
   radv_destroy_image(device, pAllocator, image);
2355
 
}
2356
 
 
2357
 
VKAPI_ATTR void VKAPI_CALL
2358
 
radv_GetImageSubresourceLayout(VkDevice _device, VkImage _image,
2359
 
                               const VkImageSubresource *pSubresource, VkSubresourceLayout *pLayout)
2360
 
{
2361
 
   RADV_FROM_HANDLE(radv_image, image, _image);
2362
 
   RADV_FROM_HANDLE(radv_device, device, _device);
2363
 
   int level = pSubresource->mipLevel;
2364
 
   int layer = pSubresource->arrayLayer;
2365
 
 
2366
 
   unsigned plane_id = 0;
2367
 
   if (vk_format_get_plane_count(image->vk_format) > 1)
2368
 
      plane_id = radv_plane_from_aspect(pSubresource->aspectMask);
2369
 
 
2370
 
   struct radv_image_plane *plane = &image->planes[plane_id];
2371
 
   struct radeon_surf *surface = &plane->surface;
2372
 
 
2373
 
   if (image->tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT) {
2374
 
      unsigned mem_plane_id = radv_plane_from_aspect(pSubresource->aspectMask);
2375
 
 
2376
 
      assert(level == 0);
2377
 
      assert(layer == 0);
2378
 
 
2379
 
      pLayout->offset = ac_surface_get_plane_offset(device->physical_device->rad_info.chip_class,
2380
 
                                                    surface, mem_plane_id, 0);
2381
 
      pLayout->rowPitch = ac_surface_get_plane_stride(device->physical_device->rad_info.chip_class,
2382
 
                                                      surface, mem_plane_id, level);
2383
 
      pLayout->arrayPitch = 0;
2384
 
      pLayout->depthPitch = 0;
2385
 
      pLayout->size = ac_surface_get_plane_size(surface, mem_plane_id);
2386
 
   } else if (device->physical_device->rad_info.chip_class >= GFX9) {
2387
 
      uint64_t level_offset = surface->is_linear ? surface->u.gfx9.offset[level] : 0;
2388
 
 
2389
 
      pLayout->offset = ac_surface_get_plane_offset(device->physical_device->rad_info.chip_class,
2390
 
                                                    &plane->surface, 0, layer) +
2391
 
                        level_offset;
2392
 
      if (image->vk_format == VK_FORMAT_R32G32B32_UINT ||
2393
 
          image->vk_format == VK_FORMAT_R32G32B32_SINT ||
2394
 
          image->vk_format == VK_FORMAT_R32G32B32_SFLOAT) {
2395
 
         /* Adjust the number of bytes between each row because
2396
 
          * the pitch is actually the number of components per
2397
 
          * row.
2398
 
          */
2399
 
         pLayout->rowPitch = surface->u.gfx9.surf_pitch * surface->bpe / 3;
2400
 
      } else {
2401
 
         uint32_t pitch =
2402
 
            surface->is_linear ? surface->u.gfx9.pitch[level] : surface->u.gfx9.surf_pitch;
2403
 
 
2404
 
         assert(util_is_power_of_two_nonzero(surface->bpe));
2405
 
         pLayout->rowPitch = pitch * surface->bpe;
2406
 
      }
2407
 
 
2408
 
      pLayout->arrayPitch = surface->u.gfx9.surf_slice_size;
2409
 
      pLayout->depthPitch = surface->u.gfx9.surf_slice_size;
2410
 
      pLayout->size = surface->u.gfx9.surf_slice_size;
2411
 
      if (image->type == VK_IMAGE_TYPE_3D)
2412
 
         pLayout->size *= u_minify(image->info.depth, level);
2413
 
   } else {
2414
 
      pLayout->offset = (uint64_t)surface->u.legacy.level[level].offset_256B * 256 +
2415
 
                        (uint64_t)surface->u.legacy.level[level].slice_size_dw * 4 * layer;
2416
 
      pLayout->rowPitch = surface->u.legacy.level[level].nblk_x * surface->bpe;
2417
 
      pLayout->arrayPitch = (uint64_t)surface->u.legacy.level[level].slice_size_dw * 4;
2418
 
      pLayout->depthPitch = (uint64_t)surface->u.legacy.level[level].slice_size_dw * 4;
2419
 
      pLayout->size = (uint64_t)surface->u.legacy.level[level].slice_size_dw * 4;
2420
 
      if (image->type == VK_IMAGE_TYPE_3D)
2421
 
         pLayout->size *= u_minify(image->info.depth, level);
2422
 
   }
2423
 
}
2424
 
 
2425
 
VKAPI_ATTR VkResult VKAPI_CALL
2426
 
radv_GetImageDrmFormatModifierPropertiesEXT(VkDevice _device, VkImage _image,
2427
 
                                            VkImageDrmFormatModifierPropertiesEXT *pProperties)
2428
 
{
2429
 
   RADV_FROM_HANDLE(radv_image, image, _image);
2430
 
 
2431
 
   pProperties->drmFormatModifier = image->planes[0].surface.modifier;
2432
 
   return VK_SUCCESS;
2433
 
}
2434
 
 
2435
 
VKAPI_ATTR VkResult VKAPI_CALL
2436
 
radv_CreateImageView(VkDevice _device, const VkImageViewCreateInfo *pCreateInfo,
2437
 
                     const VkAllocationCallbacks *pAllocator, VkImageView *pView)
2438
 
{
2439
 
   RADV_FROM_HANDLE(radv_device, device, _device);
2440
 
   struct radv_image_view *view;
2441
 
 
2442
 
   view =
2443
 
      vk_alloc2(&device->vk.alloc, pAllocator, sizeof(*view), 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
2444
 
   if (view == NULL)
2445
 
      return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
2446
 
 
2447
 
   radv_image_view_init(view, device, pCreateInfo, NULL);
2448
 
 
2449
 
   *pView = radv_image_view_to_handle(view);
2450
 
 
2451
 
   return VK_SUCCESS;
2452
 
}
2453
 
 
2454
 
VKAPI_ATTR void VKAPI_CALL
2455
 
radv_DestroyImageView(VkDevice _device, VkImageView _iview, const VkAllocationCallbacks *pAllocator)
2456
 
{
2457
 
   RADV_FROM_HANDLE(radv_device, device, _device);
2458
 
   RADV_FROM_HANDLE(radv_image_view, iview, _iview);
2459
 
 
2460
 
   if (!iview)
2461
 
      return;
2462
 
 
2463
 
   radv_image_view_finish(iview);
2464
 
   vk_free2(&device->vk.alloc, pAllocator, iview);
2465
 
}
2466
 
 
2467
 
void
2468
 
radv_buffer_view_init(struct radv_buffer_view *view, struct radv_device *device,
2469
 
                      const VkBufferViewCreateInfo *pCreateInfo)
2470
 
{
2471
 
   RADV_FROM_HANDLE(radv_buffer, buffer, pCreateInfo->buffer);
2472
 
 
2473
 
   vk_object_base_init(&device->vk, &view->base, VK_OBJECT_TYPE_BUFFER_VIEW);
2474
 
 
2475
 
   view->bo = buffer->bo;
2476
 
   view->range =
2477
 
      pCreateInfo->range == VK_WHOLE_SIZE ? buffer->size - pCreateInfo->offset : pCreateInfo->range;
2478
 
   view->vk_format = pCreateInfo->format;
2479
 
 
2480
 
   radv_make_buffer_descriptor(device, buffer, view->vk_format, pCreateInfo->offset, view->range,
2481
 
                               view->state);
2482
 
}
2483
 
 
2484
 
void
2485
 
radv_buffer_view_finish(struct radv_buffer_view *view)
2486
 
{
2487
 
   vk_object_base_finish(&view->base);
2488
 
}
2489
 
 
2490
 
VKAPI_ATTR VkResult VKAPI_CALL
2491
 
radv_CreateBufferView(VkDevice _device, const VkBufferViewCreateInfo *pCreateInfo,
2492
 
                      const VkAllocationCallbacks *pAllocator, VkBufferView *pView)
2493
 
{
2494
 
   RADV_FROM_HANDLE(radv_device, device, _device);
2495
 
   struct radv_buffer_view *view;
2496
 
 
2497
 
   view =
2498
 
      vk_alloc2(&device->vk.alloc, pAllocator, sizeof(*view), 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
2499
 
   if (!view)
2500
 
      return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
2501
 
 
2502
 
   radv_buffer_view_init(view, device, pCreateInfo);
2503
 
 
2504
 
   *pView = radv_buffer_view_to_handle(view);
2505
 
 
2506
 
   return VK_SUCCESS;
2507
 
}
2508
 
 
2509
 
VKAPI_ATTR void VKAPI_CALL
2510
 
radv_DestroyBufferView(VkDevice _device, VkBufferView bufferView,
2511
 
                       const VkAllocationCallbacks *pAllocator)
2512
 
{
2513
 
   RADV_FROM_HANDLE(radv_device, device, _device);
2514
 
   RADV_FROM_HANDLE(radv_buffer_view, view, bufferView);
2515
 
 
2516
 
   if (!view)
2517
 
      return;
2518
 
 
2519
 
   radv_buffer_view_finish(view);
2520
 
   vk_free2(&device->vk.alloc, pAllocator, view);
2521
 
}