1 /*
2 * Copyright © 2022 Collabora Ltd. and Red Hat Inc.
3 * SPDX-License-Identifier: MIT
4 */
5 #include "nvk_buffer_view.h"
6
7 #include "nil.h"
8 #include "nvk_buffer.h"
9 #include "nvk_entrypoints.h"
10 #include "nvk_device.h"
11 #include "nvk_format.h"
12 #include "nvk_physical_device.h"
13
14 #include "vk_format.h"
15
16 #include "clb097.h"
17
18 VkFormatFeatureFlags2
nvk_get_buffer_format_features(struct nvk_physical_device * pdev,VkFormat vk_format)19 nvk_get_buffer_format_features(struct nvk_physical_device *pdev,
20 VkFormat vk_format)
21 {
22 VkFormatFeatureFlags2 features = 0;
23
24 if (nvk_get_va_format(pdev, vk_format))
25 features |= VK_FORMAT_FEATURE_2_VERTEX_BUFFER_BIT;
26
27 enum pipe_format p_format = vk_format_to_pipe_format(vk_format);
28 if (nil_format_supports_buffer(&pdev->info, p_format)) {
29 features |= VK_FORMAT_FEATURE_2_UNIFORM_TEXEL_BUFFER_BIT;
30
31 if (nil_format_supports_storage(&pdev->info, p_format)) {
32 features |= VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_BIT |
33 VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT;
34 if (pdev->info.cls_eng3d >= MAXWELL_A)
35 features |= VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT;
36 }
37
38 if (p_format == PIPE_FORMAT_R32_UINT || p_format == PIPE_FORMAT_R32_SINT)
39 features |= VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_ATOMIC_BIT;
40 }
41
42 return features;
43 }
44
45 VKAPI_ATTR VkResult VKAPI_CALL
nvk_CreateBufferView(VkDevice _device,const VkBufferViewCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkBufferView * pBufferView)46 nvk_CreateBufferView(VkDevice _device,
47 const VkBufferViewCreateInfo *pCreateInfo,
48 const VkAllocationCallbacks *pAllocator,
49 VkBufferView *pBufferView)
50 {
51 VK_FROM_HANDLE(nvk_device, dev, _device);
52 VK_FROM_HANDLE(nvk_buffer, buffer, pCreateInfo->buffer);
53 struct nvk_physical_device *pdev = nvk_device_physical(dev);
54 struct nvk_buffer_view *view;
55 VkResult result;
56
57 view = vk_buffer_view_create(&dev->vk, pCreateInfo,
58 pAllocator, sizeof(*view));
59 if (!view)
60 return vk_error(dev, VK_ERROR_OUT_OF_HOST_MEMORY);
61
62 const uint64_t addr = nvk_buffer_address(buffer, view->vk.offset);
63 enum pipe_format format = vk_format_to_pipe_format(view->vk.format);
64
65 if (nvk_use_edb_buffer_views(pdev)) {
66 view->edb_desc =
67 nvk_edb_bview_cache_get_descriptor(dev, &dev->edb_bview_cache,
68 addr, view->vk.range, format);
69 } else {
70 uint32_t desc[8];
71 nil_buffer_fill_tic(&pdev->info, addr, nil_format(format),
72 view->vk.elements, &desc);
73
74 uint32_t desc_index;
75 result = nvk_descriptor_table_add(dev, &dev->images,
76 desc, sizeof(desc),
77 &desc_index);
78 if (result != VK_SUCCESS) {
79 vk_buffer_view_destroy(&dev->vk, pAllocator, &view->vk);
80 return result;
81 }
82
83 view->desc = (struct nvk_buffer_view_descriptor) {
84 .image_index = desc_index,
85 };
86 }
87
88 *pBufferView = nvk_buffer_view_to_handle(view);
89
90 return VK_SUCCESS;
91 }
92
93 VKAPI_ATTR void VKAPI_CALL
nvk_DestroyBufferView(VkDevice _device,VkBufferView bufferView,const VkAllocationCallbacks * pAllocator)94 nvk_DestroyBufferView(VkDevice _device,
95 VkBufferView bufferView,
96 const VkAllocationCallbacks *pAllocator)
97 {
98 VK_FROM_HANDLE(nvk_device, dev, _device);
99 VK_FROM_HANDLE(nvk_buffer_view, view, bufferView);
100 struct nvk_physical_device *pdev = nvk_device_physical(dev);
101
102 if (!view)
103 return;
104
105 if (!nvk_use_edb_buffer_views(pdev))
106 nvk_descriptor_table_remove(dev, &dev->images, view->desc.image_index);
107
108 vk_buffer_view_destroy(&dev->vk, pAllocator, &view->vk);
109 }
110