OSDN Git Service

anv/image: Fix usage for depthstencil images
[android-x86/external-mesa.git] / src / vulkan / anv_image.c
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
32 /**
33  * Exactly one bit must be set in \a aspect.
34  */
35 static isl_surf_usage_flags_t
36 choose_isl_surf_usage(VkImageUsageFlags vk_usage,
37                       VkImageAspectFlags aspect)
38 {
39    isl_surf_usage_flags_t isl_usage = 0;
40
41    /* FINISHME: Support aux surfaces */
42    isl_usage |= ISL_SURF_USAGE_DISABLE_AUX_BIT;
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    if (vk_usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
57       switch (aspect) {
58       default:
59          unreachable("bad VkImageAspect");
60       case VK_IMAGE_ASPECT_DEPTH_BIT:
61          isl_usage |= ISL_SURF_USAGE_DEPTH_BIT;
62          break;
63       case VK_IMAGE_ASPECT_STENCIL_BIT:
64          isl_usage |= ISL_SURF_USAGE_STENCIL_BIT;
65          break;
66       }
67    }
68
69    if (vk_usage & VK_IMAGE_USAGE_TRANSFER_SRC_BIT) {
70       /* Meta implements transfers by sampling from the source image. */
71       isl_usage |= ISL_SURF_USAGE_TEXTURE_BIT;
72    }
73
74    if (vk_usage & VK_IMAGE_USAGE_TRANSFER_DST_BIT) {
75       /* Meta implements transfers by rendering into the destination image. */
76       isl_usage |= ISL_SURF_USAGE_RENDER_TARGET_BIT;
77    }
78
79    return isl_usage;
80 }
81
82 /**
83  * Exactly one bit must be set in \a aspect.
84  */
85 static struct anv_surface *
86 get_surface(struct anv_image *image, VkImageAspectFlags aspect)
87 {
88    switch (aspect) {
89    default:
90       unreachable("bad VkImageAspect");
91    case VK_IMAGE_ASPECT_COLOR_BIT:
92       return &image->color_surface;
93    case VK_IMAGE_ASPECT_DEPTH_BIT:
94       return &image->depth_surface;
95    case VK_IMAGE_ASPECT_STENCIL_BIT:
96       return &image->stencil_surface;
97    }
98 }
99
100 /**
101  * Initialize the anv_image::*_surface selected by \a aspect. Then update the
102  * image's memory requirements (that is, the image's size and alignment).
103  *
104  * Exactly one bit must be set in \a aspect.
105  */
106 static VkResult
107 make_surface(const struct anv_device *dev,
108              struct anv_image *image,
109              const struct anv_image_create_info *anv_info,
110              VkImageAspectFlags aspect)
111 {
112    const VkImageCreateInfo *vk_info = anv_info->vk_info;
113    bool ok UNUSED;
114
115    static const enum isl_surf_dim vk_to_isl_surf_dim[] = {
116       [VK_IMAGE_TYPE_1D] = ISL_SURF_DIM_1D,
117       [VK_IMAGE_TYPE_2D] = ISL_SURF_DIM_2D,
118       [VK_IMAGE_TYPE_3D] = ISL_SURF_DIM_3D,
119    };
120
121    isl_tiling_flags_t tiling_flags = anv_info->isl_tiling_flags;
122    if (vk_info->tiling == VK_IMAGE_TILING_LINEAR)
123       tiling_flags &= ISL_TILING_LINEAR_BIT;
124
125    struct anv_surface *anv_surf = get_surface(image, aspect);
126
127    ok = isl_surf_init(&dev->isl_dev, &anv_surf->isl,
128       .dim = vk_to_isl_surf_dim[vk_info->imageType],
129       .format = anv_get_isl_format(vk_info->format, aspect,
130                                    vk_info->tiling, NULL),
131       .width = vk_info->extent.width,
132       .height = vk_info->extent.height,
133       .depth = vk_info->extent.depth,
134       .levels = vk_info->mipLevels,
135       .array_len = vk_info->arrayLayers,
136       .samples = vk_info->samples,
137       .min_alignment = 0,
138       .min_pitch = 0,
139       .usage = choose_isl_surf_usage(image->usage, aspect),
140       .tiling_flags = tiling_flags);
141
142    /* isl_surf_init() will fail only if provided invalid input. Invalid input
143     * is illegal in Vulkan.
144     */
145    assert(ok);
146
147    anv_surf->offset = align_u32(image->size, anv_surf->isl.alignment);
148    image->size = anv_surf->offset + anv_surf->isl.size;
149    image->alignment = MAX(image->alignment, anv_surf->isl.alignment);
150
151    return VK_SUCCESS;
152 }
153
154 /**
155  * Parameter @a format is required and overrides VkImageCreateInfo::format.
156  */
157 static VkImageUsageFlags
158 anv_image_get_full_usage(const VkImageCreateInfo *info,
159                          const struct anv_format *format)
160 {
161    VkImageUsageFlags usage = info->usage;
162
163    if (info->samples > 1 &&
164        (usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)) {
165       /* Meta will resolve the image by binding it as a texture. */
166       usage |= VK_IMAGE_USAGE_SAMPLED_BIT;
167    }
168
169    if (usage & VK_IMAGE_USAGE_TRANSFER_SRC_BIT) {
170       /* Meta will transfer from the image by binding it as a texture. */
171       usage |= VK_IMAGE_USAGE_SAMPLED_BIT;
172    }
173
174    if (usage & VK_IMAGE_USAGE_TRANSFER_DST_BIT) {
175       /* For non-clear transfer operations, meta will transfer to the image by
176        * binding it as a color attachment, even if the image format is not
177        * a color format.
178        */
179       usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
180
181       if (anv_format_is_depth_or_stencil(format)) {
182          /* vkCmdClearDepthStencilImage() only requires that
183           * VK_IMAGE_USAGE_TRANSFER_SRC_BIT be set. In particular, it does
184           * not require VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT. Meta
185           * clears the image, though, by binding it as a depthstencil
186           * attachment.
187           */
188          usage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
189       }
190    }
191
192    return usage;
193 }
194
195 VkResult
196 anv_image_create(VkDevice _device,
197                  const struct anv_image_create_info *create_info,
198                  const VkAllocationCallbacks* alloc,
199                  VkImage *pImage)
200 {
201    ANV_FROM_HANDLE(anv_device, device, _device);
202    const VkImageCreateInfo *pCreateInfo = create_info->vk_info;
203    struct anv_image *image = NULL;
204    const struct anv_format *format = anv_format_for_vk_format(pCreateInfo->format);
205    VkResult r;
206
207    assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO);
208
209    anv_assert(pCreateInfo->mipLevels > 0);
210    anv_assert(pCreateInfo->arrayLayers > 0);
211    anv_assert(pCreateInfo->samples > 0);
212    anv_assert(pCreateInfo->extent.width > 0);
213    anv_assert(pCreateInfo->extent.height > 0);
214    anv_assert(pCreateInfo->extent.depth > 0);
215
216    image = anv_alloc2(&device->alloc, alloc, sizeof(*image), 8,
217                       VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
218    if (!image)
219       return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
220
221    memset(image, 0, sizeof(*image));
222    image->type = pCreateInfo->imageType;
223    image->extent = pCreateInfo->extent;
224    image->vk_format = pCreateInfo->format;
225    image->format = format;
226    image->levels = pCreateInfo->mipLevels;
227    image->array_size = pCreateInfo->arrayLayers;
228    image->samples = pCreateInfo->samples;
229    image->usage = anv_image_get_full_usage(pCreateInfo, format);
230    image->tiling = pCreateInfo->tiling;
231
232    if (likely(anv_format_is_color(format))) {
233       r = make_surface(device, image, create_info,
234                        VK_IMAGE_ASPECT_COLOR_BIT);
235       if (r != VK_SUCCESS)
236          goto fail;
237    } else {
238       if (image->format->has_depth) {
239          r = make_surface(device, image, create_info,
240                           VK_IMAGE_ASPECT_DEPTH_BIT);
241          if (r != VK_SUCCESS)
242             goto fail;
243       }
244
245       if (image->format->has_stencil) {
246          r = make_surface(device, image, create_info,
247                           VK_IMAGE_ASPECT_STENCIL_BIT);
248          if (r != VK_SUCCESS)
249             goto fail;
250       }
251    }
252
253    *pImage = anv_image_to_handle(image);
254
255    return VK_SUCCESS;
256
257 fail:
258    if (image)
259       anv_free2(&device->alloc, alloc, image);
260
261    return r;
262 }
263
264 VkResult
265 anv_CreateImage(VkDevice device,
266                 const VkImageCreateInfo *pCreateInfo,
267                 const VkAllocationCallbacks *pAllocator,
268                 VkImage *pImage)
269 {
270    return anv_image_create(device,
271       &(struct anv_image_create_info) {
272          .vk_info = pCreateInfo,
273          .isl_tiling_flags = ISL_TILING_ANY_MASK,
274       },
275       pAllocator,
276       pImage);
277 }
278
279 void
280 anv_DestroyImage(VkDevice _device, VkImage _image,
281                  const VkAllocationCallbacks *pAllocator)
282 {
283    ANV_FROM_HANDLE(anv_device, device, _device);
284
285    anv_free2(&device->alloc, pAllocator, anv_image_from_handle(_image));
286 }
287
288 static void
289 anv_surface_get_subresource_layout(struct anv_image *image,
290                                    struct anv_surface *surface,
291                                    const VkImageSubresource *subresource,
292                                    VkSubresourceLayout *layout)
293 {
294    /* If we are on a non-zero mip level or array slice, we need to
295     * calculate a real offset.
296     */
297    anv_assert(subresource->mipLevel == 0);
298    anv_assert(subresource->arrayLayer == 0);
299
300    layout->offset = surface->offset;
301    layout->rowPitch = surface->isl.row_pitch;
302    layout->depthPitch = isl_surf_get_array_pitch(&surface->isl);
303    layout->arrayPitch = isl_surf_get_array_pitch(&surface->isl);
304    layout->size = surface->isl.size;
305 }
306
307 void anv_GetImageSubresourceLayout(
308     VkDevice                                    device,
309     VkImage                                     _image,
310     const VkImageSubresource*                   pSubresource,
311     VkSubresourceLayout*                        pLayout)
312 {
313    ANV_FROM_HANDLE(anv_image, image, _image);
314
315    assert(__builtin_popcount(pSubresource->aspectMask) == 1);
316
317    switch (pSubresource->aspectMask) {
318    case VK_IMAGE_ASPECT_COLOR_BIT:
319       anv_surface_get_subresource_layout(image, &image->color_surface,
320                                          pSubresource, pLayout);
321       break;
322    case VK_IMAGE_ASPECT_DEPTH_BIT:
323       anv_surface_get_subresource_layout(image, &image->depth_surface,
324                                          pSubresource, pLayout);
325       break;
326    case VK_IMAGE_ASPECT_STENCIL_BIT:
327       anv_surface_get_subresource_layout(image, &image->stencil_surface,
328                                          pSubresource, pLayout);
329       break;
330    default:
331       assert(!"Invalid image aspect");
332    }
333 }
334
335 VkResult
336 anv_validate_CreateImageView(VkDevice _device,
337                              const VkImageViewCreateInfo *pCreateInfo,
338                              const VkAllocationCallbacks *pAllocator,
339                              VkImageView *pView)
340 {
341    ANV_FROM_HANDLE(anv_image, image, pCreateInfo->image);
342    const VkImageSubresourceRange *subresource;
343    const struct anv_format *view_format_info;
344
345    /* Validate structure type before dereferencing it. */
346    assert(pCreateInfo);
347    assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO);
348    subresource = &pCreateInfo->subresourceRange;
349
350    /* Validate viewType is in range before using it. */
351    assert(pCreateInfo->viewType >= VK_IMAGE_VIEW_TYPE_BEGIN_RANGE);
352    assert(pCreateInfo->viewType <= VK_IMAGE_VIEW_TYPE_END_RANGE);
353
354    /* Validate format is in range before using it. */
355    assert(pCreateInfo->format >= VK_FORMAT_BEGIN_RANGE);
356    assert(pCreateInfo->format <= VK_FORMAT_END_RANGE);
357    view_format_info = anv_format_for_vk_format(pCreateInfo->format);
358
359    /* Validate channel swizzles. */
360    assert(pCreateInfo->components.r >= VK_COMPONENT_SWIZZLE_BEGIN_RANGE);
361    assert(pCreateInfo->components.r <= VK_COMPONENT_SWIZZLE_END_RANGE);
362    assert(pCreateInfo->components.g >= VK_COMPONENT_SWIZZLE_BEGIN_RANGE);
363    assert(pCreateInfo->components.g <= VK_COMPONENT_SWIZZLE_END_RANGE);
364    assert(pCreateInfo->components.b >= VK_COMPONENT_SWIZZLE_BEGIN_RANGE);
365    assert(pCreateInfo->components.b <= VK_COMPONENT_SWIZZLE_END_RANGE);
366    assert(pCreateInfo->components.a >= VK_COMPONENT_SWIZZLE_BEGIN_RANGE);
367    assert(pCreateInfo->components.a <= VK_COMPONENT_SWIZZLE_END_RANGE);
368
369    /* Validate subresource. */
370    assert(subresource->aspectMask != 0);
371    assert(subresource->levelCount > 0);
372    assert(subresource->layerCount > 0);
373    assert(subresource->baseMipLevel < image->levels);
374    assert(subresource->baseMipLevel + subresource->levelCount <= image->levels);
375    assert(subresource->baseArrayLayer < image->array_size);
376    assert(subresource->baseArrayLayer + subresource->layerCount <= image->array_size);
377    assert(pView);
378
379    const VkImageAspectFlags ds_flags = VK_IMAGE_ASPECT_DEPTH_BIT
380                                      | VK_IMAGE_ASPECT_STENCIL_BIT;
381
382    /* Validate format. */
383    if (subresource->aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) {
384       assert(subresource->aspectMask == VK_IMAGE_ASPECT_COLOR_BIT);
385       assert(!image->format->has_depth);
386       assert(!image->format->has_stencil);
387       assert(!view_format_info->has_depth);
388       assert(!view_format_info->has_stencil);
389       assert(view_format_info->isl_layout->bs ==
390              image->format->isl_layout->bs);
391    } else if (subresource->aspectMask & ds_flags) {
392       assert((subresource->aspectMask & ~ds_flags) == 0);
393
394       if (subresource->aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) {
395          assert(image->format->has_depth);
396          assert(view_format_info->has_depth);
397          assert(view_format_info->isl_layout->bs ==
398                 image->format->isl_layout->bs);
399       }
400
401       if (subresource->aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) {
402          /* FINISHME: Is it legal to have an R8 view of S8? */
403          assert(image->format->has_stencil);
404          assert(view_format_info->has_stencil);
405       }
406    } else {
407       assert(!"bad VkImageSubresourceRange::aspectFlags");
408    }
409
410    return anv_CreateImageView(_device, pCreateInfo, pAllocator, pView);
411 }
412
413 void
414 anv_fill_image_surface_state(struct anv_device *device, struct anv_state state,
415                              struct anv_image_view *iview,
416                              const VkImageViewCreateInfo *pCreateInfo,
417                              VkImageUsageFlagBits usage)
418 {
419    switch (device->info.gen) {
420    case 7:
421       if (device->info.is_haswell)
422          gen75_fill_image_surface_state(device, state.map, iview,
423                                         pCreateInfo, usage);
424       else
425          gen7_fill_image_surface_state(device, state.map, iview,
426                                        pCreateInfo, usage);
427       break;
428    case 8:
429       gen8_fill_image_surface_state(device, state.map, iview,
430                                     pCreateInfo, usage);
431       break;
432    case 9:
433       gen9_fill_image_surface_state(device, state.map, iview,
434                                     pCreateInfo, usage);
435       break;
436    default:
437       unreachable("unsupported gen\n");
438    }
439
440    if (!device->info.has_llc)
441       anv_state_clflush(state);
442 }
443
444 static struct anv_state
445 alloc_surface_state(struct anv_device *device,
446                     struct anv_cmd_buffer *cmd_buffer)
447 {
448       if (cmd_buffer) {
449          return anv_cmd_buffer_alloc_surface_state(cmd_buffer);
450       } else {
451          return anv_state_pool_alloc(&device->surface_state_pool, 64, 64);
452       }
453 }
454
455 static bool
456 has_matching_storage_typed_format(const struct anv_device *device,
457                                   enum isl_format format)
458 {
459    return (isl_format_get_layout(format)->bs <= 4 ||
460            (isl_format_get_layout(format)->bs <= 8 &&
461             (device->info.gen >= 8 || device->info.is_haswell)) ||
462            device->info.gen >= 9);
463 }
464
465 static VkComponentSwizzle
466 remap_swizzle(VkComponentSwizzle swizzle, VkComponentSwizzle component,
467               struct anv_format_swizzle format_swizzle)
468 {
469    if (swizzle == VK_COMPONENT_SWIZZLE_IDENTITY)
470       swizzle = component;
471
472    switch (swizzle) {
473    case VK_COMPONENT_SWIZZLE_ZERO:
474       return VK_COMPONENT_SWIZZLE_ZERO;
475    case VK_COMPONENT_SWIZZLE_ONE:
476       return VK_COMPONENT_SWIZZLE_ONE;
477    case VK_COMPONENT_SWIZZLE_R:
478       return VK_COMPONENT_SWIZZLE_R + format_swizzle.r;
479    case VK_COMPONENT_SWIZZLE_G:
480       return VK_COMPONENT_SWIZZLE_R + format_swizzle.g;
481    case VK_COMPONENT_SWIZZLE_B:
482       return VK_COMPONENT_SWIZZLE_R + format_swizzle.b;
483    case VK_COMPONENT_SWIZZLE_A:
484       return VK_COMPONENT_SWIZZLE_R + format_swizzle.a;
485    default:
486       unreachable("Invalid swizzle");
487    }
488 }
489
490 void
491 anv_image_view_init(struct anv_image_view *iview,
492                     struct anv_device *device,
493                     const VkImageViewCreateInfo* pCreateInfo,
494                     struct anv_cmd_buffer *cmd_buffer,
495                     uint32_t offset)
496 {
497    ANV_FROM_HANDLE(anv_image, image, pCreateInfo->image);
498    const VkImageSubresourceRange *range = &pCreateInfo->subresourceRange;
499    VkImageViewCreateInfo mCreateInfo;
500    memcpy(&mCreateInfo, pCreateInfo, sizeof(VkImageViewCreateInfo));
501
502    assert(range->layerCount > 0);
503    assert(range->baseMipLevel < image->levels);
504    assert(image->usage & (VK_IMAGE_USAGE_SAMPLED_BIT |
505                           VK_IMAGE_USAGE_STORAGE_BIT |
506                           VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
507                           VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT));
508
509    switch (image->type) {
510    default:
511       unreachable("bad VkImageType");
512    case VK_IMAGE_TYPE_1D:
513    case VK_IMAGE_TYPE_2D:
514       assert(range->baseArrayLayer + range->layerCount - 1 <= image->array_size);
515       break;
516    case VK_IMAGE_TYPE_3D:
517       assert(range->baseArrayLayer + range->layerCount - 1
518              <= anv_minify(image->extent.depth, range->baseMipLevel));
519       break;
520    }
521
522    struct anv_surface *surface =
523       anv_image_get_surface_for_aspect_mask(image, range->aspectMask);
524
525    iview->image = image;
526    iview->bo = image->bo;
527    iview->offset = image->offset + surface->offset + offset;
528
529    iview->aspect_mask = pCreateInfo->subresourceRange.aspectMask;
530    iview->vk_format = pCreateInfo->format;
531
532    struct anv_format_swizzle swizzle;
533    iview->format = anv_get_isl_format(pCreateInfo->format, iview->aspect_mask,
534                                       image->tiling, &swizzle);
535    iview->swizzle.r = remap_swizzle(pCreateInfo->components.r,
536                                     VK_COMPONENT_SWIZZLE_R, swizzle);
537    iview->swizzle.g = remap_swizzle(pCreateInfo->components.g,
538                                     VK_COMPONENT_SWIZZLE_G, swizzle);
539    iview->swizzle.b = remap_swizzle(pCreateInfo->components.b,
540                                     VK_COMPONENT_SWIZZLE_B, swizzle);
541    iview->swizzle.a = remap_swizzle(pCreateInfo->components.a,
542                                     VK_COMPONENT_SWIZZLE_A, swizzle);
543
544    iview->base_layer = range->baseArrayLayer;
545    iview->base_mip = range->baseMipLevel;
546
547    if (!isl_format_is_compressed(iview->format) &&
548        isl_format_is_compressed(image->format->isl_format)) {
549       /* Scale the ImageView extent by the backing Image. This is used
550        * internally when an uncompressed ImageView is created on a
551        * compressed Image. The ImageView can therefore be used for copying
552        * data from a source Image to a destination Image.
553        */
554       const struct isl_format_layout * isl_layout = image->format->isl_layout;
555
556       iview->level_0_extent.depth  = anv_minify(image->extent.depth, range->baseMipLevel);
557       iview->level_0_extent.depth  = DIV_ROUND_UP(iview->level_0_extent.depth, isl_layout->bd);
558
559       iview->level_0_extent.height = isl_surf_get_array_pitch_el_rows(&surface->isl) * image->array_size;
560       iview->level_0_extent.width  = isl_surf_get_row_pitch_el(&surface->isl);
561       mCreateInfo.subresourceRange.baseMipLevel = 0;
562       mCreateInfo.subresourceRange.baseArrayLayer = 0;
563    } else {
564       iview->level_0_extent.width  = image->extent.width;
565       iview->level_0_extent.height = image->extent.height;
566       iview->level_0_extent.depth  = image->extent.depth;
567    }
568
569    iview->extent = (VkExtent3D) {
570       .width  = anv_minify(iview->level_0_extent.width , range->baseMipLevel),
571       .height = anv_minify(iview->level_0_extent.height, range->baseMipLevel),
572       .depth  = anv_minify(iview->level_0_extent.depth , range->baseMipLevel),
573    };
574
575    if (image->usage & VK_IMAGE_USAGE_SAMPLED_BIT) {
576       iview->sampler_surface_state = alloc_surface_state(device, cmd_buffer);
577
578       anv_fill_image_surface_state(device, iview->sampler_surface_state,
579                                    iview, &mCreateInfo,
580                                    VK_IMAGE_USAGE_SAMPLED_BIT);
581    } else {
582       iview->sampler_surface_state.alloc_size = 0;
583    }
584
585    if (image->usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) {
586       iview->color_rt_surface_state = alloc_surface_state(device, cmd_buffer);
587
588       anv_fill_image_surface_state(device, iview->color_rt_surface_state,
589                                    iview, &mCreateInfo,
590                                    VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
591    } else {
592       iview->color_rt_surface_state.alloc_size = 0;
593    }
594
595    if (image->usage & VK_IMAGE_USAGE_STORAGE_BIT) {
596       iview->storage_surface_state = alloc_surface_state(device, cmd_buffer);
597
598       if (has_matching_storage_typed_format(device, iview->format))
599          anv_fill_image_surface_state(device, iview->storage_surface_state,
600                                       iview, &mCreateInfo,
601                                       VK_IMAGE_USAGE_STORAGE_BIT);
602       else
603          anv_fill_buffer_surface_state(device, iview->storage_surface_state,
604                                        ISL_FORMAT_RAW,
605                                        iview->offset,
606                                        iview->bo->size - iview->offset, 1);
607
608    } else {
609       iview->storage_surface_state.alloc_size = 0;
610    }
611 }
612
613 VkResult
614 anv_CreateImageView(VkDevice _device,
615                     const VkImageViewCreateInfo *pCreateInfo,
616                     const VkAllocationCallbacks *pAllocator,
617                     VkImageView *pView)
618 {
619    ANV_FROM_HANDLE(anv_device, device, _device);
620    struct anv_image_view *view;
621
622    view = anv_alloc2(&device->alloc, pAllocator, sizeof(*view), 8,
623                      VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
624    if (view == NULL)
625       return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
626
627    anv_image_view_init(view, device, pCreateInfo, NULL, 0);
628
629    *pView = anv_image_view_to_handle(view);
630
631    return VK_SUCCESS;
632 }
633
634 void
635 anv_DestroyImageView(VkDevice _device, VkImageView _iview,
636                      const VkAllocationCallbacks *pAllocator)
637 {
638    ANV_FROM_HANDLE(anv_device, device, _device);
639    ANV_FROM_HANDLE(anv_image_view, iview, _iview);
640
641    if (iview->color_rt_surface_state.alloc_size > 0) {
642       anv_state_pool_free(&device->surface_state_pool,
643                           iview->color_rt_surface_state);
644    }
645
646    if (iview->sampler_surface_state.alloc_size > 0) {
647       anv_state_pool_free(&device->surface_state_pool,
648                           iview->sampler_surface_state);
649    }
650
651    if (iview->storage_surface_state.alloc_size > 0) {
652       anv_state_pool_free(&device->surface_state_pool,
653                           iview->storage_surface_state);
654    }
655
656    anv_free2(&device->alloc, pAllocator, iview);
657 }
658
659 VkResult
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 = anv_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    const struct anv_format *format =
675       anv_format_for_vk_format(pCreateInfo->format);
676
677    view->format = format->isl_format;
678    view->bo = buffer->bo;
679    view->offset = buffer->offset + pCreateInfo->offset;
680    view->range = pCreateInfo->range == VK_WHOLE_SIZE ?
681                  buffer->size - view->offset : pCreateInfo->range;
682
683    if (buffer->usage & VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT) {
684       view->surface_state =
685          anv_state_pool_alloc(&device->surface_state_pool, 64, 64);
686
687       anv_fill_buffer_surface_state(device, view->surface_state,
688                                     view->format,
689                                     view->offset, view->range,
690                                     format->isl_layout->bs);
691    } else {
692       view->surface_state = (struct anv_state){ 0 };
693    }
694
695    if (buffer->usage & VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT) {
696       view->storage_surface_state =
697          anv_state_pool_alloc(&device->surface_state_pool, 64, 64);
698
699       enum isl_format storage_format =
700          has_matching_storage_typed_format(device, view->format) ?
701          isl_lower_storage_image_format(&device->isl_dev, view->format) :
702          ISL_FORMAT_RAW;
703
704       anv_fill_buffer_surface_state(device, view->storage_surface_state,
705                                     storage_format,
706                                     view->offset, view->range,
707                                     (storage_format == ISL_FORMAT_RAW ? 1 :
708                                      format->isl_layout->bs));
709
710    } else {
711       view->storage_surface_state = (struct anv_state){ 0 };
712    }
713
714    *pView = anv_buffer_view_to_handle(view);
715
716    return VK_SUCCESS;
717 }
718
719 void
720 anv_DestroyBufferView(VkDevice _device, VkBufferView bufferView,
721                       const VkAllocationCallbacks *pAllocator)
722 {
723    ANV_FROM_HANDLE(anv_device, device, _device);
724    ANV_FROM_HANDLE(anv_buffer_view, view, bufferView);
725
726    if (view->surface_state.alloc_size > 0)
727       anv_state_pool_free(&device->surface_state_pool,
728                           view->surface_state);
729
730    if (view->storage_surface_state.alloc_size > 0)
731       anv_state_pool_free(&device->surface_state_pool,
732                           view->storage_surface_state);
733
734    anv_free2(&device->alloc, pAllocator, view);
735 }
736
737 struct anv_surface *
738 anv_image_get_surface_for_aspect_mask(struct anv_image *image, VkImageAspectFlags aspect_mask)
739 {
740    switch (aspect_mask) {
741    case VK_IMAGE_ASPECT_COLOR_BIT:
742       /* Dragons will eat you.
743        *
744        * Meta attaches all destination surfaces as color render targets. Guess
745        * what surface the Meta Dragons really want.
746        */
747       if (image->format->has_depth && image->format->has_stencil) {
748          return &image->depth_surface;
749       } else if (image->format->has_depth) {
750          return &image->depth_surface;
751       } else if (image->format->has_stencil) {
752          return &image->stencil_surface;
753       } else {
754          return &image->color_surface;
755       }
756       break;
757    case VK_IMAGE_ASPECT_DEPTH_BIT:
758       assert(image->format->has_depth);
759       return &image->depth_surface;
760    case VK_IMAGE_ASPECT_STENCIL_BIT:
761       assert(image->format->has_stencil);
762       return &image->stencil_surface;
763    case VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT:
764       if (image->format->has_depth && image->format->has_stencil) {
765          /* FINISHME: The Vulkan spec (git a511ba2) requires support for
766           * combined depth stencil formats. Specifically, it states:
767           *
768           *    At least one of ename:VK_FORMAT_D24_UNORM_S8_UINT or
769           *    ename:VK_FORMAT_D32_SFLOAT_S8_UINT must be supported.
770           *
771           * Image views with both depth and stencil aspects are only valid for
772           * render target attachments, in which case
773           * cmd_buffer_emit_depth_stencil() will pick out both the depth and
774           * stencil surfaces from the underlying surface.
775           */
776          return &image->depth_surface;
777       } else if (image->format->has_depth) {
778          return &image->depth_surface;
779       } else if (image->format->has_stencil) {
780          return &image->stencil_surface;
781       }
782       /* fallthrough */
783     default:
784        unreachable("image does not have aspect");
785        return NULL;
786    }
787 }
788
789 static void
790 image_param_defaults(struct brw_image_param *param)
791 {
792    memset(param, 0, sizeof *param);
793    /* Set the swizzling shifts to all-ones to effectively disable swizzling --
794     * See emit_address_calculation() in brw_fs_surface_builder.cpp for a more
795     * detailed explanation of these parameters.
796     */
797    param->swizzling[0] = 0xff;
798    param->swizzling[1] = 0xff;
799 }
800
801 void
802 anv_image_view_fill_image_param(struct anv_device *device,
803                                 struct anv_image_view *view,
804                                 struct brw_image_param *param)
805 {
806    image_param_defaults(param);
807
808    const struct isl_surf *surf = &view->image->color_surface.isl;
809    const int cpp = isl_format_get_layout(surf->format)->bs;
810    const struct isl_extent3d image_align_sa =
811       isl_surf_get_image_alignment_sa(surf);
812
813    param->size[0] = view->extent.width;
814    param->size[1] = view->extent.height;
815    if (surf->dim == ISL_SURF_DIM_3D) {
816       param->size[2] = view->extent.depth;
817    } else {
818       param->size[2] = surf->logical_level0_px.array_len - view->base_layer;
819    }
820
821    isl_surf_get_image_offset_el(surf, view->base_mip, view->base_layer, 0,
822                                 &param->offset[0],  &param->offset[1]);
823
824    param->stride[0] = cpp;
825    param->stride[1] = surf->row_pitch / cpp;
826
827    if (device->info.gen < 9 && surf->dim == ISL_SURF_DIM_3D) {
828       param->stride[2] = util_align_npot(param->size[0], image_align_sa.w);
829       param->stride[3] = util_align_npot(param->size[1], image_align_sa.h);
830    } else {
831       param->stride[2] = 0;
832       param->stride[3] = isl_surf_get_array_pitch_el_rows(surf);
833    }
834
835    switch (surf->tiling) {
836    case ISL_TILING_LINEAR:
837       /* image_param_defaults is good enough */
838       break;
839
840    case ISL_TILING_X:
841       /* An X tile is a rectangular block of 512x8 bytes. */
842       param->tiling[0] = util_logbase2(512 / cpp);
843       param->tiling[1] = util_logbase2(8);
844
845       if (device->isl_dev.has_bit6_swizzling) {
846          /* Right shifts required to swizzle bits 9 and 10 of the memory
847           * address with bit 6.
848           */
849          param->swizzling[0] = 3;
850          param->swizzling[1] = 4;
851       }
852       break;
853
854    case ISL_TILING_Y0:
855       /* The layout of a Y-tiled surface in memory isn't really fundamentally
856        * different to the layout of an X-tiled surface, we simply pretend that
857        * the surface is broken up in a number of smaller 16Bx32 tiles, each
858        * one arranged in X-major order just like is the case for X-tiling.
859        */
860       param->tiling[0] = util_logbase2(16 / cpp);
861       param->tiling[1] = util_logbase2(32);
862
863       if (device->isl_dev.has_bit6_swizzling) {
864          /* Right shift required to swizzle bit 9 of the memory address with
865           * bit 6.
866           */
867          param->swizzling[0] = 3;
868          param->swizzling[1] = 0xff;
869       }
870       break;
871
872    default:
873       assert(!"Unhandled storage image tiling");
874    }
875
876    /* 3D textures are arranged in 2D in memory with 2^lod slices per row.  The
877     * address calculation algorithm (emit_address_calculation() in
878     * brw_fs_surface_builder.cpp) handles this as a sort of tiling with
879     * modulus equal to the LOD.
880     */
881    param->tiling[2] = (device->info.gen < 9 && surf->dim == ISL_SURF_DIM_3D ?
882                        view->base_mip : 0);
883 }
884
885 void
886 anv_buffer_view_fill_image_param(struct anv_device *device,
887                                  struct anv_buffer_view *view,
888                                  struct brw_image_param *param)
889 {
890    image_param_defaults(param);
891
892    param->stride[0] = isl_format_layouts[view->format].bs;
893    param->size[0] = view->range / param->stride[0];
894 }