/* * Copyright © 2022 Collabora Ltd. and Red Hat Inc. * SPDX-License-Identifier: MIT */ #include "nvk_buffer_view.h" #include "nil.h" #include "nvk_buffer.h" #include "nvk_entrypoints.h" #include "nvk_device.h" #include "nvk_format.h" #include "nvk_physical_device.h" #include "vk_format.h" #include "clb097.h" VkFormatFeatureFlags2 nvk_get_buffer_format_features(struct nvk_physical_device *pdev, VkFormat vk_format) { VkFormatFeatureFlags2 features = 0; if (nvk_get_va_format(pdev, vk_format)) features |= VK_FORMAT_FEATURE_2_VERTEX_BUFFER_BIT; enum pipe_format p_format = vk_format_to_pipe_format(vk_format); if (nil_format_supports_buffer(&pdev->info, p_format)) { features |= VK_FORMAT_FEATURE_2_UNIFORM_TEXEL_BUFFER_BIT; if (nil_format_supports_storage(&pdev->info, p_format)) { features |= VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT; if (pdev->info.cls_eng3d >= MAXWELL_A) features |= VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT; } if (p_format == PIPE_FORMAT_R32_UINT || p_format == PIPE_FORMAT_R32_SINT) features |= VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_ATOMIC_BIT; } return features; } VKAPI_ATTR VkResult VKAPI_CALL nvk_CreateBufferView(VkDevice _device, const VkBufferViewCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkBufferView *pBufferView) { VK_FROM_HANDLE(nvk_device, dev, _device); VK_FROM_HANDLE(nvk_buffer, buffer, pCreateInfo->buffer); struct nvk_physical_device *pdev = nvk_device_physical(dev); struct nvk_buffer_view *view; VkResult result; view = vk_buffer_view_create(&dev->vk, pCreateInfo, pAllocator, sizeof(*view)); if (!view) return vk_error(dev, VK_ERROR_OUT_OF_HOST_MEMORY); const uint64_t addr = nvk_buffer_address(buffer, view->vk.offset); enum pipe_format format = vk_format_to_pipe_format(view->vk.format); if (nvk_use_edb_buffer_views(pdev)) { view->edb_desc = nvk_edb_bview_cache_get_descriptor(dev, &dev->edb_bview_cache, addr, view->vk.range, format); } else { uint32_t desc[8]; nil_buffer_fill_tic(&pdev->info, addr, nil_format(format), view->vk.elements, &desc); uint32_t desc_index; result = nvk_descriptor_table_add(dev, &dev->images, desc, sizeof(desc), &desc_index); if (result != VK_SUCCESS) { vk_buffer_view_destroy(&dev->vk, pAllocator, &view->vk); return result; } view->desc = (struct nvk_buffer_view_descriptor) { .image_index = desc_index, }; } *pBufferView = nvk_buffer_view_to_handle(view); return VK_SUCCESS; } VKAPI_ATTR void VKAPI_CALL nvk_DestroyBufferView(VkDevice _device, VkBufferView bufferView, const VkAllocationCallbacks *pAllocator) { VK_FROM_HANDLE(nvk_device, dev, _device); VK_FROM_HANDLE(nvk_buffer_view, view, bufferView); struct nvk_physical_device *pdev = nvk_device_physical(dev); if (!view) return; if (!nvk_use_edb_buffer_views(pdev)) nvk_descriptor_table_remove(dev, &dev->images, view->desc.image_index); vk_buffer_view_destroy(&dev->vk, pAllocator, &view->vk); }