• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2015 Intel Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21  * IN THE SOFTWARE.
22  */
23 
24 #include <assert.h>
25 #include <stdbool.h>
26 #include <string.h>
27 #include <unistd.h>
28 #include <fcntl.h>
29 
30 #include "anv_private.h"
31 #include "util/debug.h"
32 
33 #include "vk_format_info.h"
34 
35 /**
36  * Exactly one bit must be set in \a aspect.
37  */
38 static isl_surf_usage_flags_t
choose_isl_surf_usage(VkImageUsageFlags vk_usage,VkImageAspectFlags aspect)39 choose_isl_surf_usage(VkImageUsageFlags vk_usage,
40                       VkImageAspectFlags aspect)
41 {
42    isl_surf_usage_flags_t isl_usage = 0;
43 
44    if (vk_usage & VK_IMAGE_USAGE_SAMPLED_BIT)
45       isl_usage |= ISL_SURF_USAGE_TEXTURE_BIT;
46 
47    if (vk_usage & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)
48       isl_usage |= ISL_SURF_USAGE_TEXTURE_BIT;
49 
50    if (vk_usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)
51       isl_usage |= ISL_SURF_USAGE_RENDER_TARGET_BIT;
52 
53    if (vk_usage & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT)
54       isl_usage |= ISL_SURF_USAGE_CUBE_BIT;
55 
56    /* Even if we're only using it for transfer operations, clears to depth and
57     * stencil images happen as depth and stencil so they need the right ISL
58     * usage bits or else things will fall apart.
59     */
60    switch (aspect) {
61    case VK_IMAGE_ASPECT_DEPTH_BIT:
62       isl_usage |= ISL_SURF_USAGE_DEPTH_BIT;
63       break;
64    case VK_IMAGE_ASPECT_STENCIL_BIT:
65       isl_usage |= ISL_SURF_USAGE_STENCIL_BIT;
66       break;
67    case VK_IMAGE_ASPECT_COLOR_BIT:
68       break;
69    default:
70       unreachable("bad VkImageAspect");
71    }
72 
73    if (vk_usage & VK_IMAGE_USAGE_TRANSFER_SRC_BIT) {
74       /* blorp implements transfers by sampling from the source image. */
75       isl_usage |= ISL_SURF_USAGE_TEXTURE_BIT;
76    }
77 
78    if (vk_usage & VK_IMAGE_USAGE_TRANSFER_DST_BIT &&
79        aspect == VK_IMAGE_ASPECT_COLOR_BIT) {
80       /* blorp implements transfers by rendering into the destination image.
81        * Only request this with color images, as we deal with depth/stencil
82        * formats differently. */
83       isl_usage |= ISL_SURF_USAGE_RENDER_TARGET_BIT;
84    }
85 
86    return isl_usage;
87 }
88 
89 /**
90  * Exactly one bit must be set in \a aspect.
91  */
92 static struct anv_surface *
get_surface(struct anv_image * image,VkImageAspectFlags aspect)93 get_surface(struct anv_image *image, VkImageAspectFlags aspect)
94 {
95    switch (aspect) {
96    default:
97       unreachable("bad VkImageAspect");
98    case VK_IMAGE_ASPECT_COLOR_BIT:
99       return &image->color_surface;
100    case VK_IMAGE_ASPECT_DEPTH_BIT:
101       return &image->depth_surface;
102    case VK_IMAGE_ASPECT_STENCIL_BIT:
103       return &image->stencil_surface;
104    }
105 }
106 
107 static void
add_surface(struct anv_image * image,struct anv_surface * surf)108 add_surface(struct anv_image *image, struct anv_surface *surf)
109 {
110    assert(surf->isl.size > 0); /* isl surface must be initialized */
111 
112    surf->offset = align_u32(image->size, surf->isl.alignment);
113    image->size = surf->offset + surf->isl.size;
114    image->alignment = MAX2(image->alignment, surf->isl.alignment);
115 }
116 
117 /**
118  * Initialize the anv_image::*_surface selected by \a aspect. Then update the
119  * image's memory requirements (that is, the image's size and alignment).
120  *
121  * Exactly one bit must be set in \a aspect.
122  */
123 static VkResult
make_surface(const struct anv_device * dev,struct anv_image * image,const struct anv_image_create_info * anv_info,VkImageAspectFlags aspect)124 make_surface(const struct anv_device *dev,
125              struct anv_image *image,
126              const struct anv_image_create_info *anv_info,
127              VkImageAspectFlags aspect)
128 {
129    const VkImageCreateInfo *vk_info = anv_info->vk_info;
130    bool ok UNUSED;
131 
132    static const enum isl_surf_dim vk_to_isl_surf_dim[] = {
133       [VK_IMAGE_TYPE_1D] = ISL_SURF_DIM_1D,
134       [VK_IMAGE_TYPE_2D] = ISL_SURF_DIM_2D,
135       [VK_IMAGE_TYPE_3D] = ISL_SURF_DIM_3D,
136    };
137 
138    /* Translate the Vulkan tiling to an equivalent ISL tiling, then filter the
139     * result with an optionally provided ISL tiling argument.
140     */
141    isl_tiling_flags_t tiling_flags =
142       (vk_info->tiling == VK_IMAGE_TILING_LINEAR) ?
143       ISL_TILING_LINEAR_BIT : ISL_TILING_ANY_MASK;
144 
145    if (anv_info->isl_tiling_flags)
146       tiling_flags &= anv_info->isl_tiling_flags;
147 
148    assert(tiling_flags);
149 
150    struct anv_surface *anv_surf = get_surface(image, aspect);
151 
152    image->extent = anv_sanitize_image_extent(vk_info->imageType,
153                                              vk_info->extent);
154 
155    enum isl_format format = anv_get_isl_format(&dev->info, vk_info->format,
156                                                aspect, vk_info->tiling);
157    assert(format != ISL_FORMAT_UNSUPPORTED);
158 
159    ok = isl_surf_init(&dev->isl_dev, &anv_surf->isl,
160       .dim = vk_to_isl_surf_dim[vk_info->imageType],
161       .format = format,
162       .width = image->extent.width,
163       .height = image->extent.height,
164       .depth = image->extent.depth,
165       .levels = vk_info->mipLevels,
166       .array_len = vk_info->arrayLayers,
167       .samples = vk_info->samples,
168       .min_alignment = 0,
169       .min_pitch = anv_info->stride,
170       .usage = choose_isl_surf_usage(image->usage, aspect),
171       .tiling_flags = tiling_flags);
172 
173    /* isl_surf_init() will fail only if provided invalid input. Invalid input
174     * is illegal in Vulkan.
175     */
176    assert(ok);
177 
178    add_surface(image, anv_surf);
179 
180    /* Add a HiZ surface to a depth buffer that will be used for rendering.
181     */
182    if (aspect == VK_IMAGE_ASPECT_DEPTH_BIT) {
183       /* We don't advertise that depth buffers could be used as storage
184        * images.
185        */
186        assert(!(image->usage & VK_IMAGE_USAGE_STORAGE_BIT));
187 
188       /* Allow the user to control HiZ enabling. Disable by default on gen7
189        * because resolves are not currently implemented pre-BDW.
190        */
191       if (!(image->usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)) {
192          /* It will never be used as an attachment, HiZ is pointless. */
193       } else if (image->usage & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT) {
194          /* From the 1.0.37 spec:
195           *
196           *    "An attachment used as an input attachment and depth/stencil
197           *    attachment must be in either VK_IMAGE_LAYOUT_GENERAL or
198           *    VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL."
199           *
200           * It will never have a layout of
201           * VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, so HiZ is
202           * currently pointless. If transfer operations learn to use the HiZ
203           * buffer, we can enable HiZ for VK_IMAGE_LAYOUT_GENERAL and support
204           * input attachments.
205           */
206          anv_finishme("Implement HiZ for input attachments");
207       } else if (!env_var_as_boolean("INTEL_VK_HIZ", dev->info.gen >= 8)) {
208          anv_finishme("Implement gen7 HiZ");
209       } else if (vk_info->mipLevels > 1) {
210          anv_finishme("Test multi-LOD HiZ");
211       } else if (vk_info->arrayLayers > 1) {
212          anv_finishme("Implement multi-arrayLayer HiZ clears and resolves");
213       } else if (dev->info.gen == 8 && vk_info->samples > 1) {
214          anv_finishme("Test gen8 multisampled HiZ");
215       } else {
216          assert(image->aux_surface.isl.size == 0);
217          isl_surf_get_hiz_surf(&dev->isl_dev, &image->depth_surface.isl,
218                                &image->aux_surface.isl);
219          add_surface(image, &image->aux_surface);
220          image->aux_usage = ISL_AUX_USAGE_HIZ;
221       }
222    } else if (aspect == VK_IMAGE_ASPECT_COLOR_BIT && vk_info->samples == 1) {
223       if (!unlikely(INTEL_DEBUG & DEBUG_NO_RBC)) {
224          assert(image->aux_surface.isl.size == 0);
225          ok = isl_surf_get_ccs_surf(&dev->isl_dev, &anv_surf->isl,
226                                     &image->aux_surface.isl);
227          if (ok) {
228             add_surface(image, &image->aux_surface);
229 
230             /* For images created without MUTABLE_FORMAT_BIT set, we know that
231              * they will always be used with the original format.  In
232              * particular, they will always be used with a format that
233              * supports color compression.  This means that it's safe to just
234              * leave compression on at all times for these formats.
235              */
236             if (!(vk_info->flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT) &&
237                 isl_format_supports_lossless_compression(&dev->info, format)) {
238                if (vk_info->usage & VK_IMAGE_USAGE_STORAGE_BIT) {
239                   /*
240                    * For now, we leave compression off for anything that may
241                    * be used as a storage image.  This is because accessing
242                    * storage images may involve ccs-incompatible views or even
243                    * untyped messages which don't support compression at all.
244                    */
245                   anv_finishme("Enable CCS for storage images");
246                } else {
247                   image->aux_usage = ISL_AUX_USAGE_CCS_E;
248                }
249             }
250          }
251       }
252    }
253 
254    return VK_SUCCESS;
255 }
256 
257 VkResult
anv_image_create(VkDevice _device,const struct anv_image_create_info * create_info,const VkAllocationCallbacks * alloc,VkImage * pImage)258 anv_image_create(VkDevice _device,
259                  const struct anv_image_create_info *create_info,
260                  const VkAllocationCallbacks* alloc,
261                  VkImage *pImage)
262 {
263    ANV_FROM_HANDLE(anv_device, device, _device);
264    const VkImageCreateInfo *pCreateInfo = create_info->vk_info;
265    struct anv_image *image = NULL;
266    VkResult r;
267 
268    assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO);
269 
270    anv_assert(pCreateInfo->mipLevels > 0);
271    anv_assert(pCreateInfo->arrayLayers > 0);
272    anv_assert(pCreateInfo->samples > 0);
273    anv_assert(pCreateInfo->extent.width > 0);
274    anv_assert(pCreateInfo->extent.height > 0);
275    anv_assert(pCreateInfo->extent.depth > 0);
276 
277    image = vk_alloc2(&device->alloc, alloc, sizeof(*image), 8,
278                       VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
279    if (!image)
280       return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
281 
282    memset(image, 0, sizeof(*image));
283    image->type = pCreateInfo->imageType;
284    image->extent = pCreateInfo->extent;
285    image->vk_format = pCreateInfo->format;
286    image->aspects = vk_format_aspects(image->vk_format);
287    image->levels = pCreateInfo->mipLevels;
288    image->array_size = pCreateInfo->arrayLayers;
289    image->samples = pCreateInfo->samples;
290    image->usage = pCreateInfo->usage;
291    image->tiling = pCreateInfo->tiling;
292    image->aux_usage = ISL_AUX_USAGE_NONE;
293 
294    uint32_t b;
295    for_each_bit(b, image->aspects) {
296       r = make_surface(device, image, create_info, (1 << b));
297       if (r != VK_SUCCESS)
298          goto fail;
299    }
300 
301    *pImage = anv_image_to_handle(image);
302 
303    return VK_SUCCESS;
304 
305 fail:
306    if (image)
307       vk_free2(&device->alloc, alloc, image);
308 
309    return r;
310 }
311 
312 VkResult
anv_CreateImage(VkDevice device,const VkImageCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkImage * pImage)313 anv_CreateImage(VkDevice device,
314                 const VkImageCreateInfo *pCreateInfo,
315                 const VkAllocationCallbacks *pAllocator,
316                 VkImage *pImage)
317 {
318    return anv_image_create(device,
319       &(struct anv_image_create_info) {
320          .vk_info = pCreateInfo,
321       },
322       pAllocator,
323       pImage);
324 }
325 
326 void
anv_DestroyImage(VkDevice _device,VkImage _image,const VkAllocationCallbacks * pAllocator)327 anv_DestroyImage(VkDevice _device, VkImage _image,
328                  const VkAllocationCallbacks *pAllocator)
329 {
330    ANV_FROM_HANDLE(anv_device, device, _device);
331    ANV_FROM_HANDLE(anv_image, image, _image);
332 
333    if (!image)
334       return;
335 
336    vk_free2(&device->alloc, pAllocator, image);
337 }
338 
anv_BindImageMemory(VkDevice _device,VkImage _image,VkDeviceMemory _memory,VkDeviceSize memoryOffset)339 VkResult anv_BindImageMemory(
340     VkDevice                                    _device,
341     VkImage                                     _image,
342     VkDeviceMemory                              _memory,
343     VkDeviceSize                                memoryOffset)
344 {
345    ANV_FROM_HANDLE(anv_device, device, _device);
346    ANV_FROM_HANDLE(anv_device_memory, mem, _memory);
347    ANV_FROM_HANDLE(anv_image, image, _image);
348 
349    if (mem == NULL) {
350       image->bo = NULL;
351       image->offset = 0;
352       return VK_SUCCESS;
353    }
354 
355    image->bo = &mem->bo;
356    image->offset = memoryOffset;
357 
358    if (image->aux_surface.isl.size > 0) {
359 
360       /* The offset and size must be a multiple of 4K or else the
361        * anv_gem_mmap call below will return NULL.
362        */
363       assert((image->offset + image->aux_surface.offset) % 4096 == 0);
364       assert(image->aux_surface.isl.size % 4096 == 0);
365 
366       /* Auxiliary surfaces need to have their memory cleared to 0 before they
367        * can be used.  For CCS surfaces, this puts them in the "resolved"
368        * state so they can be used with CCS enabled before we ever touch it
369        * from the GPU.  For HiZ, we need something valid or else we may get
370        * GPU hangs on some hardware and 0 works fine.
371        */
372       void *map = anv_gem_mmap(device, image->bo->gem_handle,
373                                image->offset + image->aux_surface.offset,
374                                image->aux_surface.isl.size,
375                                device->info.has_llc ? 0 : I915_MMAP_WC);
376 
377       /* If anv_gem_mmap returns NULL, it's likely that the kernel was
378        * not able to find space on the host to create a proper mapping.
379        */
380       if (map == NULL)
381          return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
382 
383       memset(map, 0, image->aux_surface.isl.size);
384 
385       anv_gem_munmap(map, image->aux_surface.isl.size);
386    }
387 
388    return VK_SUCCESS;
389 }
390 
391 static void
anv_surface_get_subresource_layout(struct anv_image * image,struct anv_surface * surface,const VkImageSubresource * subresource,VkSubresourceLayout * layout)392 anv_surface_get_subresource_layout(struct anv_image *image,
393                                    struct anv_surface *surface,
394                                    const VkImageSubresource *subresource,
395                                    VkSubresourceLayout *layout)
396 {
397    /* If we are on a non-zero mip level or array slice, we need to
398     * calculate a real offset.
399     */
400    anv_assert(subresource->mipLevel == 0);
401    anv_assert(subresource->arrayLayer == 0);
402 
403    layout->offset = surface->offset;
404    layout->rowPitch = surface->isl.row_pitch;
405    layout->depthPitch = isl_surf_get_array_pitch(&surface->isl);
406    layout->arrayPitch = isl_surf_get_array_pitch(&surface->isl);
407    layout->size = surface->isl.size;
408 }
409 
anv_GetImageSubresourceLayout(VkDevice device,VkImage _image,const VkImageSubresource * pSubresource,VkSubresourceLayout * pLayout)410 void anv_GetImageSubresourceLayout(
411     VkDevice                                    device,
412     VkImage                                     _image,
413     const VkImageSubresource*                   pSubresource,
414     VkSubresourceLayout*                        pLayout)
415 {
416    ANV_FROM_HANDLE(anv_image, image, _image);
417 
418    assert(__builtin_popcount(pSubresource->aspectMask) == 1);
419 
420    switch (pSubresource->aspectMask) {
421    case VK_IMAGE_ASPECT_COLOR_BIT:
422       anv_surface_get_subresource_layout(image, &image->color_surface,
423                                          pSubresource, pLayout);
424       break;
425    case VK_IMAGE_ASPECT_DEPTH_BIT:
426       anv_surface_get_subresource_layout(image, &image->depth_surface,
427                                          pSubresource, pLayout);
428       break;
429    case VK_IMAGE_ASPECT_STENCIL_BIT:
430       anv_surface_get_subresource_layout(image, &image->stencil_surface,
431                                          pSubresource, pLayout);
432       break;
433    default:
434       assert(!"Invalid image aspect");
435    }
436 }
437 
438 static struct anv_state
alloc_surface_state(struct anv_device * device)439 alloc_surface_state(struct anv_device *device)
440 {
441    return anv_state_pool_alloc(&device->surface_state_pool, 64, 64);
442 }
443 
444 static enum isl_channel_select
remap_swizzle(VkComponentSwizzle swizzle,VkComponentSwizzle component,struct isl_swizzle format_swizzle)445 remap_swizzle(VkComponentSwizzle swizzle, VkComponentSwizzle component,
446               struct isl_swizzle format_swizzle)
447 {
448    if (swizzle == VK_COMPONENT_SWIZZLE_IDENTITY)
449       swizzle = component;
450 
451    switch (swizzle) {
452    case VK_COMPONENT_SWIZZLE_ZERO:  return ISL_CHANNEL_SELECT_ZERO;
453    case VK_COMPONENT_SWIZZLE_ONE:   return ISL_CHANNEL_SELECT_ONE;
454    case VK_COMPONENT_SWIZZLE_R:     return format_swizzle.r;
455    case VK_COMPONENT_SWIZZLE_G:     return format_swizzle.g;
456    case VK_COMPONENT_SWIZZLE_B:     return format_swizzle.b;
457    case VK_COMPONENT_SWIZZLE_A:     return format_swizzle.a;
458    default:
459       unreachable("Invalid swizzle");
460    }
461 }
462 
463 
464 VkResult
anv_CreateImageView(VkDevice _device,const VkImageViewCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkImageView * pView)465 anv_CreateImageView(VkDevice _device,
466                     const VkImageViewCreateInfo *pCreateInfo,
467                     const VkAllocationCallbacks *pAllocator,
468                     VkImageView *pView)
469 {
470    ANV_FROM_HANDLE(anv_device, device, _device);
471    ANV_FROM_HANDLE(anv_image, image, pCreateInfo->image);
472    struct anv_image_view *iview;
473 
474    iview = vk_alloc2(&device->alloc, pAllocator, sizeof(*iview), 8,
475                       VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
476    if (iview == NULL)
477       return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
478 
479    const VkImageSubresourceRange *range = &pCreateInfo->subresourceRange;
480 
481    assert(range->layerCount > 0);
482    assert(range->baseMipLevel < image->levels);
483    assert(image->usage & (VK_IMAGE_USAGE_SAMPLED_BIT |
484                           VK_IMAGE_USAGE_STORAGE_BIT |
485                           VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
486                           VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT));
487 
488    switch (image->type) {
489    default:
490       unreachable("bad VkImageType");
491    case VK_IMAGE_TYPE_1D:
492    case VK_IMAGE_TYPE_2D:
493       assert(range->baseArrayLayer + anv_get_layerCount(image, range) - 1 <= image->array_size);
494       break;
495    case VK_IMAGE_TYPE_3D:
496       assert(range->baseArrayLayer + anv_get_layerCount(image, range) - 1
497              <= anv_minify(image->extent.depth, range->baseMipLevel));
498       break;
499    }
500 
501    const struct anv_surface *surface =
502       anv_image_get_surface_for_aspect_mask(image, range->aspectMask);
503 
504    iview->image = image;
505    iview->bo = image->bo;
506    iview->offset = image->offset + surface->offset;
507 
508    iview->aspect_mask = pCreateInfo->subresourceRange.aspectMask;
509    iview->vk_format = pCreateInfo->format;
510 
511    struct anv_format format = anv_get_format(&device->info, pCreateInfo->format,
512                                              range->aspectMask, image->tiling);
513 
514    iview->isl = (struct isl_view) {
515       .format = format.isl_format,
516       .base_level = range->baseMipLevel,
517       .levels = anv_get_levelCount(image, range),
518       .base_array_layer = range->baseArrayLayer,
519       .array_len = anv_get_layerCount(image, range),
520       .swizzle = {
521          .r = remap_swizzle(pCreateInfo->components.r,
522                             VK_COMPONENT_SWIZZLE_R, format.swizzle),
523          .g = remap_swizzle(pCreateInfo->components.g,
524                             VK_COMPONENT_SWIZZLE_G, format.swizzle),
525          .b = remap_swizzle(pCreateInfo->components.b,
526                             VK_COMPONENT_SWIZZLE_B, format.swizzle),
527          .a = remap_swizzle(pCreateInfo->components.a,
528                             VK_COMPONENT_SWIZZLE_A, format.swizzle),
529       },
530    };
531 
532    iview->extent = (VkExtent3D) {
533       .width  = anv_minify(image->extent.width , range->baseMipLevel),
534       .height = anv_minify(image->extent.height, range->baseMipLevel),
535       .depth  = anv_minify(image->extent.depth , range->baseMipLevel),
536    };
537 
538    if (image->type == VK_IMAGE_TYPE_3D) {
539       iview->isl.base_array_layer = 0;
540       iview->isl.array_len = iview->extent.depth;
541    }
542 
543    if (pCreateInfo->viewType == VK_IMAGE_VIEW_TYPE_CUBE ||
544        pCreateInfo->viewType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) {
545       iview->isl.usage = ISL_SURF_USAGE_CUBE_BIT;
546    } else {
547       iview->isl.usage = 0;
548    }
549 
550    /* If the HiZ buffer can be sampled from, set the constant clear color.
551     * If it cannot, disable the isl aux usage flag.
552     */
553    float red_clear_color = 0.0f;
554    enum isl_aux_usage surf_usage = image->aux_usage;
555    if (image->aux_usage == ISL_AUX_USAGE_HIZ) {
556       if (iview->aspect_mask & VK_IMAGE_ASPECT_DEPTH_BIT &&
557           anv_can_sample_with_hiz(device->info.gen, image->samples)) {
558          /* When a HiZ buffer is sampled on gen9+, ensure that
559           * the constant fast clear value is set in the surface state.
560           */
561          if (device->info.gen >= 9)
562             red_clear_color = ANV_HZ_FC_VAL;
563       } else {
564          surf_usage = ISL_AUX_USAGE_NONE;
565       }
566    }
567 
568    /* Input attachment surfaces for color are allocated and filled
569     * out at BeginRenderPass time because they need compression information.
570     * Compression is not yet enabled for depth textures and stencil doesn't
571     * allow compression so we can just use the texture surface state from the
572     * view.
573     */
574    if (image->usage & VK_IMAGE_USAGE_SAMPLED_BIT ||
575        (image->usage & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT &&
576         !(iview->aspect_mask & VK_IMAGE_ASPECT_COLOR_BIT))) {
577       iview->sampler_surface_state = alloc_surface_state(device);
578 
579       struct isl_view view = iview->isl;
580       view.usage |= ISL_SURF_USAGE_TEXTURE_BIT;
581       isl_surf_fill_state(&device->isl_dev,
582                           iview->sampler_surface_state.map,
583                           .surf = &surface->isl,
584                           .view = &view,
585                           .clear_color.f32 = { red_clear_color,},
586                           .aux_surf = &image->aux_surface.isl,
587                           .aux_usage = image->aux_usage,
588                           .mocs = device->default_mocs);
589 
590       if (!device->info.has_llc)
591          anv_state_clflush(iview->sampler_surface_state);
592    } else {
593       iview->sampler_surface_state.alloc_size = 0;
594    }
595 
596    /* NOTE: This one needs to go last since it may stomp isl_view.format */
597    if (image->usage & VK_IMAGE_USAGE_STORAGE_BIT) {
598       iview->storage_surface_state = alloc_surface_state(device);
599 
600       if (isl_has_matching_typed_storage_image_format(&device->info,
601                                                       format.isl_format)) {
602          struct isl_view view = iview->isl;
603          view.usage |= ISL_SURF_USAGE_STORAGE_BIT;
604          view.format = isl_lower_storage_image_format(&device->info,
605                                                       format.isl_format);
606          isl_surf_fill_state(&device->isl_dev,
607                              iview->storage_surface_state.map,
608                              .surf = &surface->isl,
609                              .view = &view,
610                              .aux_surf = &image->aux_surface.isl,
611                              .aux_usage = image->aux_usage,
612                              .mocs = device->default_mocs);
613       } else {
614          anv_fill_buffer_surface_state(device, iview->storage_surface_state,
615                                        ISL_FORMAT_RAW,
616                                        iview->offset,
617                                        iview->bo->size - iview->offset, 1);
618       }
619 
620       isl_surf_fill_image_param(&device->isl_dev,
621                                 &iview->storage_image_param,
622                                 &surface->isl, &iview->isl);
623 
624       if (!device->info.has_llc)
625          anv_state_clflush(iview->storage_surface_state);
626    } else {
627       iview->storage_surface_state.alloc_size = 0;
628    }
629 
630    *pView = anv_image_view_to_handle(iview);
631 
632    return VK_SUCCESS;
633 }
634 
635 void
anv_DestroyImageView(VkDevice _device,VkImageView _iview,const VkAllocationCallbacks * pAllocator)636 anv_DestroyImageView(VkDevice _device, VkImageView _iview,
637                      const VkAllocationCallbacks *pAllocator)
638 {
639    ANV_FROM_HANDLE(anv_device, device, _device);
640    ANV_FROM_HANDLE(anv_image_view, iview, _iview);
641 
642    if (!iview)
643       return;
644 
645    if (iview->sampler_surface_state.alloc_size > 0) {
646       anv_state_pool_free(&device->surface_state_pool,
647                           iview->sampler_surface_state);
648    }
649 
650    if (iview->storage_surface_state.alloc_size > 0) {
651       anv_state_pool_free(&device->surface_state_pool,
652                           iview->storage_surface_state);
653    }
654 
655    vk_free2(&device->alloc, pAllocator, iview);
656 }
657 
658 
659 VkResult
anv_CreateBufferView(VkDevice _device,const VkBufferViewCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkBufferView * pView)660 anv_CreateBufferView(VkDevice _device,
661                      const VkBufferViewCreateInfo *pCreateInfo,
662                      const VkAllocationCallbacks *pAllocator,
663                      VkBufferView *pView)
664 {
665    ANV_FROM_HANDLE(anv_device, device, _device);
666    ANV_FROM_HANDLE(anv_buffer, buffer, pCreateInfo->buffer);
667    struct anv_buffer_view *view;
668 
669    view = vk_alloc2(&device->alloc, pAllocator, sizeof(*view), 8,
670                      VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
671    if (!view)
672       return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
673 
674    /* TODO: Handle the format swizzle? */
675 
676    view->format = anv_get_isl_format(&device->info, pCreateInfo->format,
677                                      VK_IMAGE_ASPECT_COLOR_BIT,
678                                      VK_IMAGE_TILING_LINEAR);
679    const uint32_t format_bs = isl_format_get_layout(view->format)->bpb / 8;
680    view->bo = buffer->bo;
681    view->offset = buffer->offset + pCreateInfo->offset;
682    view->range = pCreateInfo->range == VK_WHOLE_SIZE ?
683                  buffer->size - pCreateInfo->offset : pCreateInfo->range;
684    view->range = align_down_npot_u32(view->range, format_bs);
685 
686    if (buffer->usage & VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT) {
687       view->surface_state = alloc_surface_state(device);
688 
689       anv_fill_buffer_surface_state(device, view->surface_state,
690                                     view->format,
691                                     view->offset, view->range, format_bs);
692    } else {
693       view->surface_state = (struct anv_state){ 0 };
694    }
695 
696    if (buffer->usage & VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT) {
697       view->storage_surface_state = alloc_surface_state(device);
698 
699       enum isl_format storage_format =
700          isl_has_matching_typed_storage_image_format(&device->info,
701                                                      view->format) ?
702          isl_lower_storage_image_format(&device->info, view->format) :
703          ISL_FORMAT_RAW;
704 
705       anv_fill_buffer_surface_state(device, view->storage_surface_state,
706                                     storage_format,
707                                     view->offset, view->range,
708                                     (storage_format == ISL_FORMAT_RAW ? 1 :
709                                      isl_format_get_layout(storage_format)->bpb / 8));
710 
711       isl_buffer_fill_image_param(&device->isl_dev,
712                                   &view->storage_image_param,
713                                   view->format, view->range);
714    } else {
715       view->storage_surface_state = (struct anv_state){ 0 };
716    }
717 
718    *pView = anv_buffer_view_to_handle(view);
719 
720    return VK_SUCCESS;
721 }
722 
723 void
anv_DestroyBufferView(VkDevice _device,VkBufferView bufferView,const VkAllocationCallbacks * pAllocator)724 anv_DestroyBufferView(VkDevice _device, VkBufferView bufferView,
725                       const VkAllocationCallbacks *pAllocator)
726 {
727    ANV_FROM_HANDLE(anv_device, device, _device);
728    ANV_FROM_HANDLE(anv_buffer_view, view, bufferView);
729 
730    if (!view)
731       return;
732 
733    if (view->surface_state.alloc_size > 0)
734       anv_state_pool_free(&device->surface_state_pool,
735                           view->surface_state);
736 
737    if (view->storage_surface_state.alloc_size > 0)
738       anv_state_pool_free(&device->surface_state_pool,
739                           view->storage_surface_state);
740 
741    vk_free2(&device->alloc, pAllocator, view);
742 }
743 
744 const struct anv_surface *
anv_image_get_surface_for_aspect_mask(const struct anv_image * image,VkImageAspectFlags aspect_mask)745 anv_image_get_surface_for_aspect_mask(const struct anv_image *image,
746                                       VkImageAspectFlags aspect_mask)
747 {
748    switch (aspect_mask) {
749    case VK_IMAGE_ASPECT_COLOR_BIT:
750       assert(image->aspects == VK_IMAGE_ASPECT_COLOR_BIT);
751       return &image->color_surface;
752    case VK_IMAGE_ASPECT_DEPTH_BIT:
753       assert(image->aspects & VK_IMAGE_ASPECT_DEPTH_BIT);
754       return &image->depth_surface;
755    case VK_IMAGE_ASPECT_STENCIL_BIT:
756       assert(image->aspects & VK_IMAGE_ASPECT_STENCIL_BIT);
757       return &image->stencil_surface;
758    case VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT:
759       /* FINISHME: The Vulkan spec (git a511ba2) requires support for
760        * combined depth stencil formats. Specifically, it states:
761        *
762        *    At least one of ename:VK_FORMAT_D24_UNORM_S8_UINT or
763        *    ename:VK_FORMAT_D32_SFLOAT_S8_UINT must be supported.
764        *
765        * Image views with both depth and stencil aspects are only valid for
766        * render target attachments, in which case
767        * cmd_buffer_emit_depth_stencil() will pick out both the depth and
768        * stencil surfaces from the underlying surface.
769        */
770       if (image->aspects & VK_IMAGE_ASPECT_DEPTH_BIT) {
771          return &image->depth_surface;
772       } else {
773          assert(image->aspects == VK_IMAGE_ASPECT_STENCIL_BIT);
774          return &image->stencil_surface;
775       }
776     default:
777        unreachable("image does not have aspect");
778        return NULL;
779    }
780 }
781