OSDN Git Service

virgl: add openarena readpixels workaround.
[android-x86/external-mesa.git] / src / intel / 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 #include "vk_format_info.h"
33
34 /**
35  * Exactly one bit must be set in \a aspect.
36  */
37 static isl_surf_usage_flags_t
38 choose_isl_surf_usage(VkImageUsageFlags vk_usage,
39                       VkImageAspectFlags aspect)
40 {
41    isl_surf_usage_flags_t isl_usage = 0;
42
43    /* FINISHME: Support aux surfaces */
44    isl_usage |= ISL_SURF_USAGE_DISABLE_AUX_BIT;
45
46    if (vk_usage & VK_IMAGE_USAGE_SAMPLED_BIT)
47       isl_usage |= ISL_SURF_USAGE_TEXTURE_BIT;
48
49    if (vk_usage & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)
50       isl_usage |= ISL_SURF_USAGE_TEXTURE_BIT;
51
52    if (vk_usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)
53       isl_usage |= ISL_SURF_USAGE_RENDER_TARGET_BIT;
54
55    if (vk_usage & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT)
56       isl_usage |= ISL_SURF_USAGE_CUBE_BIT;
57
58    if (vk_usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
59       switch (aspect) {
60       default:
61          unreachable("bad VkImageAspect");
62       case VK_IMAGE_ASPECT_DEPTH_BIT:
63          isl_usage |= ISL_SURF_USAGE_DEPTH_BIT;
64          break;
65       case VK_IMAGE_ASPECT_STENCIL_BIT:
66          isl_usage |= ISL_SURF_USAGE_STENCIL_BIT;
67          break;
68       }
69    }
70
71    if (vk_usage & VK_IMAGE_USAGE_TRANSFER_SRC_BIT) {
72       /* Meta implements transfers by sampling from the source image. */
73       isl_usage |= ISL_SURF_USAGE_TEXTURE_BIT;
74    }
75
76    if (vk_usage & VK_IMAGE_USAGE_TRANSFER_DST_BIT) {
77       /* Meta implements transfers by rendering into the destination image. */
78       isl_usage |= ISL_SURF_USAGE_RENDER_TARGET_BIT;
79    }
80
81    return isl_usage;
82 }
83
84 /**
85  * Exactly one bit must be set in \a aspect.
86  */
87 static struct anv_surface *
88 get_surface(struct anv_image *image, VkImageAspectFlags aspect)
89 {
90    switch (aspect) {
91    default:
92       unreachable("bad VkImageAspect");
93    case VK_IMAGE_ASPECT_COLOR_BIT:
94       return &image->color_surface;
95    case VK_IMAGE_ASPECT_DEPTH_BIT:
96       return &image->depth_surface;
97    case VK_IMAGE_ASPECT_STENCIL_BIT:
98       return &image->stencil_surface;
99    }
100 }
101
102 /**
103  * Initialize the anv_image::*_surface selected by \a aspect. Then update the
104  * image's memory requirements (that is, the image's size and alignment).
105  *
106  * Exactly one bit must be set in \a aspect.
107  */
108 static VkResult
109 make_surface(const struct anv_device *dev,
110              struct anv_image *image,
111              const struct anv_image_create_info *anv_info,
112              VkImageAspectFlags aspect)
113 {
114    const VkImageCreateInfo *vk_info = anv_info->vk_info;
115    bool ok UNUSED;
116
117    static const enum isl_surf_dim vk_to_isl_surf_dim[] = {
118       [VK_IMAGE_TYPE_1D] = ISL_SURF_DIM_1D,
119       [VK_IMAGE_TYPE_2D] = ISL_SURF_DIM_2D,
120       [VK_IMAGE_TYPE_3D] = ISL_SURF_DIM_3D,
121    };
122
123    isl_tiling_flags_t tiling_flags = anv_info->isl_tiling_flags;
124    if (vk_info->tiling == VK_IMAGE_TILING_LINEAR)
125       tiling_flags = ISL_TILING_LINEAR_BIT;
126
127    struct anv_surface *anv_surf = get_surface(image, aspect);
128
129    image->extent = anv_sanitize_image_extent(vk_info->imageType,
130                                              vk_info->extent);
131
132    ok = isl_surf_init(&dev->isl_dev, &anv_surf->isl,
133       .dim = vk_to_isl_surf_dim[vk_info->imageType],
134       .format = anv_get_isl_format(&dev->info, vk_info->format,
135                                    aspect, vk_info->tiling),
136       .width = image->extent.width,
137       .height = image->extent.height,
138       .depth = image->extent.depth,
139       .levels = vk_info->mipLevels,
140       .array_len = vk_info->arrayLayers,
141       .samples = vk_info->samples,
142       .min_alignment = 0,
143       .min_pitch = anv_info->stride,
144       .usage = choose_isl_surf_usage(image->usage, aspect),
145       .tiling_flags = tiling_flags);
146
147    /* isl_surf_init() will fail only if provided invalid input. Invalid input
148     * is illegal in Vulkan.
149     */
150    assert(ok);
151
152    anv_surf->offset = align_u32(image->size, anv_surf->isl.alignment);
153    image->size = anv_surf->offset + anv_surf->isl.size;
154    image->alignment = MAX(image->alignment, anv_surf->isl.alignment);
155
156    return VK_SUCCESS;
157 }
158
159 /**
160  * Parameter @a format is required and overrides VkImageCreateInfo::format.
161  */
162 static VkImageUsageFlags
163 anv_image_get_full_usage(const VkImageCreateInfo *info,
164                          VkImageAspectFlags aspects)
165 {
166    VkImageUsageFlags usage = info->usage;
167
168    if (info->samples > 1 &&
169        (usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)) {
170       /* Meta will resolve the image by binding it as a texture. */
171       usage |= VK_IMAGE_USAGE_SAMPLED_BIT;
172    }
173
174    if (usage & VK_IMAGE_USAGE_TRANSFER_SRC_BIT) {
175       /* Meta will transfer from the image by binding it as a texture. */
176       usage |= VK_IMAGE_USAGE_SAMPLED_BIT;
177    }
178
179    if (usage & VK_IMAGE_USAGE_TRANSFER_DST_BIT) {
180       /* For non-clear transfer operations, meta will transfer to the image by
181        * binding it as a color attachment, even if the image format is not
182        * a color format.
183        */
184       usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
185
186       if (aspects & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) {
187          /* vkCmdClearDepthStencilImage() only requires that
188           * VK_IMAGE_USAGE_TRANSFER_SRC_BIT be set. In particular, it does
189           * not require VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT. Meta
190           * clears the image, though, by binding it as a depthstencil
191           * attachment.
192           */
193          usage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
194       }
195    }
196
197    return usage;
198 }
199
200 VkResult
201 anv_image_create(VkDevice _device,
202                  const struct anv_image_create_info *create_info,
203                  const VkAllocationCallbacks* alloc,
204                  VkImage *pImage)
205 {
206    ANV_FROM_HANDLE(anv_device, device, _device);
207    const VkImageCreateInfo *pCreateInfo = create_info->vk_info;
208    struct anv_image *image = NULL;
209    VkResult r;
210
211    assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO);
212
213    anv_assert(pCreateInfo->mipLevels > 0);
214    anv_assert(pCreateInfo->arrayLayers > 0);
215    anv_assert(pCreateInfo->samples > 0);
216    anv_assert(pCreateInfo->extent.width > 0);
217    anv_assert(pCreateInfo->extent.height > 0);
218    anv_assert(pCreateInfo->extent.depth > 0);
219
220    image = anv_alloc2(&device->alloc, alloc, sizeof(*image), 8,
221                       VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
222    if (!image)
223       return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
224
225    memset(image, 0, sizeof(*image));
226    image->type = pCreateInfo->imageType;
227    image->extent = pCreateInfo->extent;
228    image->vk_format = pCreateInfo->format;
229    image->aspects = vk_format_aspects(image->vk_format);
230    image->levels = pCreateInfo->mipLevels;
231    image->array_size = pCreateInfo->arrayLayers;
232    image->samples = pCreateInfo->samples;
233    image->usage = anv_image_get_full_usage(pCreateInfo, image->aspects);
234    image->tiling = pCreateInfo->tiling;
235
236    uint32_t b;
237    for_each_bit(b, image->aspects) {
238       r = make_surface(device, image, create_info, (1 << b));
239       if (r != VK_SUCCESS)
240          goto fail;
241    }
242
243    *pImage = anv_image_to_handle(image);
244
245    return VK_SUCCESS;
246
247 fail:
248    if (image)
249       anv_free2(&device->alloc, alloc, image);
250
251    return r;
252 }
253
254 VkResult
255 anv_CreateImage(VkDevice device,
256                 const VkImageCreateInfo *pCreateInfo,
257                 const VkAllocationCallbacks *pAllocator,
258                 VkImage *pImage)
259 {
260    return anv_image_create(device,
261       &(struct anv_image_create_info) {
262          .vk_info = pCreateInfo,
263          .isl_tiling_flags = ISL_TILING_ANY_MASK,
264       },
265       pAllocator,
266       pImage);
267 }
268
269 void
270 anv_DestroyImage(VkDevice _device, VkImage _image,
271                  const VkAllocationCallbacks *pAllocator)
272 {
273    ANV_FROM_HANDLE(anv_device, device, _device);
274
275    anv_free2(&device->alloc, pAllocator, anv_image_from_handle(_image));
276 }
277
278 static void
279 anv_surface_get_subresource_layout(struct anv_image *image,
280                                    struct anv_surface *surface,
281                                    const VkImageSubresource *subresource,
282                                    VkSubresourceLayout *layout)
283 {
284    /* If we are on a non-zero mip level or array slice, we need to
285     * calculate a real offset.
286     */
287    anv_assert(subresource->mipLevel == 0);
288    anv_assert(subresource->arrayLayer == 0);
289
290    layout->offset = surface->offset;
291    layout->rowPitch = surface->isl.row_pitch;
292    layout->depthPitch = isl_surf_get_array_pitch(&surface->isl);
293    layout->arrayPitch = isl_surf_get_array_pitch(&surface->isl);
294    layout->size = surface->isl.size;
295 }
296
297 void anv_GetImageSubresourceLayout(
298     VkDevice                                    device,
299     VkImage                                     _image,
300     const VkImageSubresource*                   pSubresource,
301     VkSubresourceLayout*                        pLayout)
302 {
303    ANV_FROM_HANDLE(anv_image, image, _image);
304
305    assert(__builtin_popcount(pSubresource->aspectMask) == 1);
306
307    switch (pSubresource->aspectMask) {
308    case VK_IMAGE_ASPECT_COLOR_BIT:
309       anv_surface_get_subresource_layout(image, &image->color_surface,
310                                          pSubresource, pLayout);
311       break;
312    case VK_IMAGE_ASPECT_DEPTH_BIT:
313       anv_surface_get_subresource_layout(image, &image->depth_surface,
314                                          pSubresource, pLayout);
315       break;
316    case VK_IMAGE_ASPECT_STENCIL_BIT:
317       anv_surface_get_subresource_layout(image, &image->stencil_surface,
318                                          pSubresource, pLayout);
319       break;
320    default:
321       assert(!"Invalid image aspect");
322    }
323 }
324
325 VkResult
326 anv_validate_CreateImageView(VkDevice _device,
327                              const VkImageViewCreateInfo *pCreateInfo,
328                              const VkAllocationCallbacks *pAllocator,
329                              VkImageView *pView)
330 {
331    ANV_FROM_HANDLE(anv_image, image, pCreateInfo->image);
332    const VkImageSubresourceRange *subresource;
333
334    /* Validate structure type before dereferencing it. */
335    assert(pCreateInfo);
336    assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO);
337    subresource = &pCreateInfo->subresourceRange;
338
339    /* Validate viewType is in range before using it. */
340    assert(pCreateInfo->viewType >= VK_IMAGE_VIEW_TYPE_BEGIN_RANGE);
341    assert(pCreateInfo->viewType <= VK_IMAGE_VIEW_TYPE_END_RANGE);
342
343    /* Validate format is in range before using it. */
344    assert(pCreateInfo->format >= VK_FORMAT_BEGIN_RANGE);
345    assert(pCreateInfo->format <= VK_FORMAT_END_RANGE);
346
347    /* Validate channel swizzles. */
348    assert(pCreateInfo->components.r >= VK_COMPONENT_SWIZZLE_BEGIN_RANGE);
349    assert(pCreateInfo->components.r <= VK_COMPONENT_SWIZZLE_END_RANGE);
350    assert(pCreateInfo->components.g >= VK_COMPONENT_SWIZZLE_BEGIN_RANGE);
351    assert(pCreateInfo->components.g <= VK_COMPONENT_SWIZZLE_END_RANGE);
352    assert(pCreateInfo->components.b >= VK_COMPONENT_SWIZZLE_BEGIN_RANGE);
353    assert(pCreateInfo->components.b <= VK_COMPONENT_SWIZZLE_END_RANGE);
354    assert(pCreateInfo->components.a >= VK_COMPONENT_SWIZZLE_BEGIN_RANGE);
355    assert(pCreateInfo->components.a <= VK_COMPONENT_SWIZZLE_END_RANGE);
356
357    /* Validate subresource. */
358    assert(subresource->aspectMask != 0);
359    assert(subresource->levelCount > 0);
360    assert(subresource->layerCount > 0);
361    assert(subresource->baseMipLevel < image->levels);
362    assert(subresource->baseMipLevel + anv_get_levelCount(image, subresource) <= image->levels);
363    assert(subresource->baseArrayLayer < image->array_size);
364    assert(subresource->baseArrayLayer + anv_get_layerCount(image, subresource) <= image->array_size);
365    assert(pView);
366
367    MAYBE_UNUSED const VkImageAspectFlags view_format_aspects =
368       vk_format_aspects(pCreateInfo->format);
369
370    const VkImageAspectFlags ds_flags = VK_IMAGE_ASPECT_DEPTH_BIT
371                                      | VK_IMAGE_ASPECT_STENCIL_BIT;
372
373    /* Validate format. */
374    if (subresource->aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) {
375       assert(subresource->aspectMask == VK_IMAGE_ASPECT_COLOR_BIT);
376       assert(image->aspects == VK_IMAGE_ASPECT_COLOR_BIT);
377       assert(view_format_aspects == VK_IMAGE_ASPECT_COLOR_BIT);
378    } else if (subresource->aspectMask & ds_flags) {
379       assert((subresource->aspectMask & ~ds_flags) == 0);
380
381       assert(pCreateInfo->format == image->vk_format);
382
383       if (subresource->aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) {
384          assert(image->aspects & VK_IMAGE_ASPECT_DEPTH_BIT);
385          assert(view_format_aspects & VK_IMAGE_ASPECT_DEPTH_BIT);
386       }
387
388       if (subresource->aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) {
389          /* FINISHME: Is it legal to have an R8 view of S8? */
390          assert(image->aspects & VK_IMAGE_ASPECT_STENCIL_BIT);
391          assert(view_format_aspects & VK_IMAGE_ASPECT_STENCIL_BIT);
392       }
393    } else {
394       assert(!"bad VkImageSubresourceRange::aspectFlags");
395    }
396
397    return anv_CreateImageView(_device, pCreateInfo, pAllocator, pView);
398 }
399
400 static struct anv_state
401 alloc_surface_state(struct anv_device *device,
402                     struct anv_cmd_buffer *cmd_buffer)
403 {
404       if (cmd_buffer) {
405          return anv_cmd_buffer_alloc_surface_state(cmd_buffer);
406       } else {
407          return anv_state_pool_alloc(&device->surface_state_pool, 64, 64);
408       }
409 }
410
411 static enum isl_channel_select
412 remap_swizzle(VkComponentSwizzle swizzle, VkComponentSwizzle component,
413               struct anv_format_swizzle format_swizzle)
414 {
415    if (swizzle == VK_COMPONENT_SWIZZLE_IDENTITY)
416       swizzle = component;
417
418    switch (swizzle) {
419    case VK_COMPONENT_SWIZZLE_ZERO:  return ISL_CHANNEL_SELECT_ZERO;
420    case VK_COMPONENT_SWIZZLE_ONE:   return ISL_CHANNEL_SELECT_ONE;
421    case VK_COMPONENT_SWIZZLE_R:     return format_swizzle.r;
422    case VK_COMPONENT_SWIZZLE_G:     return format_swizzle.g;
423    case VK_COMPONENT_SWIZZLE_B:     return format_swizzle.b;
424    case VK_COMPONENT_SWIZZLE_A:     return format_swizzle.a;
425    default:
426       unreachable("Invalid swizzle");
427    }
428 }
429
430 void
431 anv_image_view_init(struct anv_image_view *iview,
432                     struct anv_device *device,
433                     const VkImageViewCreateInfo* pCreateInfo,
434                     struct anv_cmd_buffer *cmd_buffer,
435                     VkImageUsageFlags usage_mask)
436 {
437    ANV_FROM_HANDLE(anv_image, image, pCreateInfo->image);
438    const VkImageSubresourceRange *range = &pCreateInfo->subresourceRange;
439
440    assert(range->layerCount > 0);
441    assert(range->baseMipLevel < image->levels);
442    assert(image->usage & (VK_IMAGE_USAGE_SAMPLED_BIT |
443                           VK_IMAGE_USAGE_STORAGE_BIT |
444                           VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
445                           VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT));
446
447    switch (image->type) {
448    default:
449       unreachable("bad VkImageType");
450    case VK_IMAGE_TYPE_1D:
451    case VK_IMAGE_TYPE_2D:
452       assert(range->baseArrayLayer + anv_get_layerCount(image, range) - 1 <= image->array_size);
453       break;
454    case VK_IMAGE_TYPE_3D:
455       assert(range->baseArrayLayer + anv_get_layerCount(image, range) - 1
456              <= anv_minify(image->extent.depth, range->baseMipLevel));
457       break;
458    }
459
460    struct anv_surface *surface =
461       anv_image_get_surface_for_aspect_mask(image, range->aspectMask);
462
463    iview->image = image;
464    iview->bo = image->bo;
465    iview->offset = image->offset + surface->offset;
466
467    iview->aspect_mask = pCreateInfo->subresourceRange.aspectMask;
468    iview->vk_format = pCreateInfo->format;
469
470    struct anv_format format = anv_get_format(&device->info, pCreateInfo->format,
471                                              range->aspectMask, image->tiling);
472
473    iview->base_layer = range->baseArrayLayer;
474    iview->base_mip = range->baseMipLevel;
475
476    struct isl_view isl_view = {
477       .format = format.isl_format,
478       .base_level = range->baseMipLevel,
479       .levels = anv_get_levelCount(image, range),
480       .base_array_layer = range->baseArrayLayer,
481       .array_len = anv_get_layerCount(image, range),
482       .channel_select = {
483          remap_swizzle(pCreateInfo->components.r,
484                        VK_COMPONENT_SWIZZLE_R, format.swizzle),
485          remap_swizzle(pCreateInfo->components.g,
486                        VK_COMPONENT_SWIZZLE_G, format.swizzle),
487          remap_swizzle(pCreateInfo->components.b,
488                        VK_COMPONENT_SWIZZLE_B, format.swizzle),
489          remap_swizzle(pCreateInfo->components.a,
490                        VK_COMPONENT_SWIZZLE_A, format.swizzle),
491       },
492    };
493
494    iview->extent = (VkExtent3D) {
495       .width  = anv_minify(image->extent.width , range->baseMipLevel),
496       .height = anv_minify(image->extent.height, range->baseMipLevel),
497       .depth  = anv_minify(image->extent.depth , range->baseMipLevel),
498    };
499
500    isl_surf_usage_flags_t cube_usage;
501    if (pCreateInfo->viewType == VK_IMAGE_VIEW_TYPE_CUBE ||
502        pCreateInfo->viewType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) {
503       cube_usage = ISL_SURF_USAGE_CUBE_BIT;
504    } else {
505       cube_usage = 0;
506    }
507
508    if (image->usage & usage_mask & VK_IMAGE_USAGE_SAMPLED_BIT) {
509       iview->sampler_surface_state = alloc_surface_state(device, cmd_buffer);
510
511       isl_view.usage = cube_usage | ISL_SURF_USAGE_TEXTURE_BIT;
512       isl_surf_fill_state(&device->isl_dev,
513                           iview->sampler_surface_state.map,
514                           .surf = &surface->isl,
515                           .view = &isl_view,
516                           .mocs = device->default_mocs);
517
518       if (!device->info.has_llc)
519          anv_state_clflush(iview->sampler_surface_state);
520    } else {
521       iview->sampler_surface_state.alloc_size = 0;
522    }
523
524    if (image->usage & usage_mask & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) {
525       iview->color_rt_surface_state = alloc_surface_state(device, cmd_buffer);
526
527       isl_view.usage = cube_usage | ISL_SURF_USAGE_RENDER_TARGET_BIT;
528       isl_surf_fill_state(&device->isl_dev,
529                           iview->color_rt_surface_state.map,
530                           .surf = &surface->isl,
531                           .view = &isl_view,
532                           .mocs = device->default_mocs);
533
534       if (!device->info.has_llc)
535          anv_state_clflush(iview->color_rt_surface_state);
536    } else {
537       iview->color_rt_surface_state.alloc_size = 0;
538    }
539
540    /* NOTE: This one needs to go last since it may stomp isl_view.format */
541    if (image->usage & usage_mask & VK_IMAGE_USAGE_STORAGE_BIT) {
542       iview->storage_surface_state = alloc_surface_state(device, cmd_buffer);
543
544       if (isl_has_matching_typed_storage_image_format(&device->info,
545                                                       format.isl_format)) {
546          isl_view.usage = cube_usage | ISL_SURF_USAGE_STORAGE_BIT;
547          isl_view.format = isl_lower_storage_image_format(&device->info,
548                                                           isl_view.format);
549          isl_surf_fill_state(&device->isl_dev,
550                              iview->storage_surface_state.map,
551                              .surf = &surface->isl,
552                              .view = &isl_view,
553                              .mocs = device->default_mocs);
554       } else {
555          anv_fill_buffer_surface_state(device, iview->storage_surface_state,
556                                        ISL_FORMAT_RAW,
557                                        iview->offset,
558                                        iview->bo->size - iview->offset, 1);
559       }
560
561       isl_surf_fill_image_param(&device->isl_dev,
562                                 &iview->storage_image_param,
563                                 &surface->isl, &isl_view);
564
565       if (!device->info.has_llc)
566          anv_state_clflush(iview->storage_surface_state);
567    } else {
568       iview->storage_surface_state.alloc_size = 0;
569    }
570 }
571
572 VkResult
573 anv_CreateImageView(VkDevice _device,
574                     const VkImageViewCreateInfo *pCreateInfo,
575                     const VkAllocationCallbacks *pAllocator,
576                     VkImageView *pView)
577 {
578    ANV_FROM_HANDLE(anv_device, device, _device);
579    struct anv_image_view *view;
580
581    view = anv_alloc2(&device->alloc, pAllocator, sizeof(*view), 8,
582                      VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
583    if (view == NULL)
584       return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
585
586    anv_image_view_init(view, device, pCreateInfo, NULL, ~0);
587
588    *pView = anv_image_view_to_handle(view);
589
590    return VK_SUCCESS;
591 }
592
593 void
594 anv_DestroyImageView(VkDevice _device, VkImageView _iview,
595                      const VkAllocationCallbacks *pAllocator)
596 {
597    ANV_FROM_HANDLE(anv_device, device, _device);
598    ANV_FROM_HANDLE(anv_image_view, iview, _iview);
599
600    if (iview->color_rt_surface_state.alloc_size > 0) {
601       anv_state_pool_free(&device->surface_state_pool,
602                           iview->color_rt_surface_state);
603    }
604
605    if (iview->sampler_surface_state.alloc_size > 0) {
606       anv_state_pool_free(&device->surface_state_pool,
607                           iview->sampler_surface_state);
608    }
609
610    if (iview->storage_surface_state.alloc_size > 0) {
611       anv_state_pool_free(&device->surface_state_pool,
612                           iview->storage_surface_state);
613    }
614
615    anv_free2(&device->alloc, pAllocator, iview);
616 }
617
618
619 void anv_buffer_view_init(struct anv_buffer_view *view,
620                           struct anv_device *device,
621                           const VkBufferViewCreateInfo* pCreateInfo,
622                           struct anv_cmd_buffer *cmd_buffer)
623 {
624    ANV_FROM_HANDLE(anv_buffer, buffer, pCreateInfo->buffer);
625
626    /* TODO: Handle the format swizzle? */
627
628    view->format = anv_get_isl_format(&device->info, pCreateInfo->format,
629                                      VK_IMAGE_ASPECT_COLOR_BIT,
630                                      VK_IMAGE_TILING_LINEAR);
631    view->bo = buffer->bo;
632    view->offset = buffer->offset + pCreateInfo->offset;
633    view->range = pCreateInfo->range == VK_WHOLE_SIZE ?
634                  buffer->size - view->offset : pCreateInfo->range;
635
636    if (buffer->usage & VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT) {
637       view->surface_state = alloc_surface_state(device, cmd_buffer);
638
639       anv_fill_buffer_surface_state(device, view->surface_state,
640                                     view->format,
641                                     view->offset, view->range,
642                                     isl_format_get_layout(view->format)->bs);
643    } else {
644       view->surface_state = (struct anv_state){ 0 };
645    }
646
647    if (buffer->usage & VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT) {
648       view->storage_surface_state = alloc_surface_state(device, cmd_buffer);
649
650       enum isl_format storage_format =
651          isl_has_matching_typed_storage_image_format(&device->info,
652                                                      view->format) ?
653          isl_lower_storage_image_format(&device->info, view->format) :
654          ISL_FORMAT_RAW;
655
656       anv_fill_buffer_surface_state(device, view->storage_surface_state,
657                                     storage_format,
658                                     view->offset, view->range,
659                                     (storage_format == ISL_FORMAT_RAW ? 1 :
660                                      isl_format_get_layout(storage_format)->bs));
661
662       isl_buffer_fill_image_param(&device->isl_dev,
663                                   &view->storage_image_param,
664                                   view->format, view->range);
665    } else {
666       view->storage_surface_state = (struct anv_state){ 0 };
667    }
668 }
669
670 VkResult
671 anv_CreateBufferView(VkDevice _device,
672                      const VkBufferViewCreateInfo *pCreateInfo,
673                      const VkAllocationCallbacks *pAllocator,
674                      VkBufferView *pView)
675 {
676    ANV_FROM_HANDLE(anv_device, device, _device);
677    struct anv_buffer_view *view;
678
679    view = anv_alloc2(&device->alloc, pAllocator, sizeof(*view), 8,
680                      VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
681    if (!view)
682       return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
683
684    anv_buffer_view_init(view, device, pCreateInfo, NULL);
685
686    *pView = anv_buffer_view_to_handle(view);
687
688    return VK_SUCCESS;
689 }
690
691 void
692 anv_DestroyBufferView(VkDevice _device, VkBufferView bufferView,
693                       const VkAllocationCallbacks *pAllocator)
694 {
695    ANV_FROM_HANDLE(anv_device, device, _device);
696    ANV_FROM_HANDLE(anv_buffer_view, view, bufferView);
697
698    if (view->surface_state.alloc_size > 0)
699       anv_state_pool_free(&device->surface_state_pool,
700                           view->surface_state);
701
702    if (view->storage_surface_state.alloc_size > 0)
703       anv_state_pool_free(&device->surface_state_pool,
704                           view->storage_surface_state);
705
706    anv_free2(&device->alloc, pAllocator, view);
707 }
708
709 struct anv_surface *
710 anv_image_get_surface_for_aspect_mask(struct anv_image *image, VkImageAspectFlags aspect_mask)
711 {
712    switch (aspect_mask) {
713    case VK_IMAGE_ASPECT_COLOR_BIT:
714       /* Dragons will eat you.
715        *
716        * Meta attaches all destination surfaces as color render targets. Guess
717        * what surface the Meta Dragons really want.
718        */
719       if (image->aspects & VK_IMAGE_ASPECT_DEPTH_BIT) {
720          return &image->depth_surface;
721       } else if (image->aspects & VK_IMAGE_ASPECT_STENCIL_BIT) {
722          return &image->stencil_surface;
723       } else {
724          assert(image->aspects == VK_IMAGE_ASPECT_COLOR_BIT);
725          return &image->color_surface;
726       }
727       break;
728    case VK_IMAGE_ASPECT_DEPTH_BIT:
729       assert(image->aspects & VK_IMAGE_ASPECT_DEPTH_BIT);
730       return &image->depth_surface;
731    case VK_IMAGE_ASPECT_STENCIL_BIT:
732       assert(image->aspects & VK_IMAGE_ASPECT_STENCIL_BIT);
733       return &image->stencil_surface;
734    case VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT:
735       /* FINISHME: The Vulkan spec (git a511ba2) requires support for
736        * combined depth stencil formats. Specifically, it states:
737        *
738        *    At least one of ename:VK_FORMAT_D24_UNORM_S8_UINT or
739        *    ename:VK_FORMAT_D32_SFLOAT_S8_UINT must be supported.
740        *
741        * Image views with both depth and stencil aspects are only valid for
742        * render target attachments, in which case
743        * cmd_buffer_emit_depth_stencil() will pick out both the depth and
744        * stencil surfaces from the underlying surface.
745        */
746       if (image->aspects & VK_IMAGE_ASPECT_DEPTH_BIT) {
747          return &image->depth_surface;
748       } else {
749          assert(image->aspects == VK_IMAGE_ASPECT_STENCIL_BIT);
750          return &image->stencil_surface;
751       }
752     default:
753        unreachable("image does not have aspect");
754        return NULL;
755    }
756 }