Path: blob/21.2-virgl/src/gallium/frontends/lavapipe/lvp_image.c
4565 views
/*1* Copyright © 2019 Red Hat.2*3* Permission is hereby granted, free of charge, to any person obtaining a4* copy of this software and associated documentation files (the "Software"),5* to deal in the Software without restriction, including without limitation6* the rights to use, copy, modify, merge, publish, distribute, sublicense,7* and/or sell copies of the Software, and to permit persons to whom the8* Software is furnished to do so, subject to the following conditions:9*10* The above copyright notice and this permission notice (including the next11* paragraph) shall be included in all copies or substantial portions of the12* Software.13*14* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL17* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER18* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING19* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS20* IN THE SOFTWARE.21*/2223#include "lvp_private.h"24#include "util/format/u_format.h"25#include "util/u_inlines.h"26#include "pipe/p_state.h"2728VkResult29lvp_image_create(VkDevice _device,30const struct lvp_image_create_info *create_info,31const VkAllocationCallbacks* alloc,32VkImage *pImage)33{34LVP_FROM_HANDLE(lvp_device, device, _device);35const VkImageCreateInfo *pCreateInfo = create_info->vk_info;36struct lvp_image *image;3738assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO);3940image = vk_zalloc2(&device->vk.alloc, alloc, sizeof(*image), 8,41VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);42if (image == NULL)43return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);4445vk_object_base_init(&device->vk, &image->base, VK_OBJECT_TYPE_IMAGE);46image->alignment = 16;47image->type = pCreateInfo->imageType;48{49struct pipe_resource template;5051memset(&template, 0, sizeof(template));5253template.screen = device->pscreen;54switch (pCreateInfo->imageType) {55case VK_IMAGE_TYPE_1D:56template.target = pCreateInfo->arrayLayers > 1 ? PIPE_TEXTURE_1D_ARRAY : PIPE_TEXTURE_1D;57break;58default:59case VK_IMAGE_TYPE_2D:60template.target = pCreateInfo->arrayLayers > 1 ? PIPE_TEXTURE_2D_ARRAY : PIPE_TEXTURE_2D;61break;62case VK_IMAGE_TYPE_3D:63template.target = PIPE_TEXTURE_3D;64break;65}6667if (pCreateInfo->usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)68template.bind |= PIPE_BIND_RENDER_TARGET;6970if (pCreateInfo->usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)71template.bind |= PIPE_BIND_DEPTH_STENCIL;7273if (pCreateInfo->usage & VK_IMAGE_USAGE_SAMPLED_BIT)74template.bind |= PIPE_BIND_SAMPLER_VIEW;7576if (pCreateInfo->usage & VK_IMAGE_USAGE_STORAGE_BIT)77template.bind |= PIPE_BIND_SHADER_IMAGE;7879template.format = lvp_vk_format_to_pipe_format(pCreateInfo->format);80template.width0 = pCreateInfo->extent.width;81template.height0 = pCreateInfo->extent.height;82template.depth0 = pCreateInfo->extent.depth;83template.array_size = pCreateInfo->arrayLayers;84template.last_level = pCreateInfo->mipLevels - 1;85template.nr_samples = pCreateInfo->samples;86template.nr_storage_samples = pCreateInfo->samples;87if (create_info->bind_flags)88template.bind = create_info->bind_flags;89image->bo = device->pscreen->resource_create_unbacked(device->pscreen,90&template,91&image->size);92if (!image->bo)93return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);94}95*pImage = lvp_image_to_handle(image);9697return VK_SUCCESS;98}99100struct lvp_image *101lvp_swapchain_get_image(VkSwapchainKHR swapchain,102uint32_t index)103{104uint32_t n_images = index + 1;105VkImage *images = malloc(sizeof(*images) * n_images);106VkResult result = wsi_common_get_images(swapchain, &n_images, images);107108if (result != VK_SUCCESS && result != VK_INCOMPLETE) {109free(images);110return NULL;111}112113LVP_FROM_HANDLE(lvp_image, image, images[index]);114free(images);115116return image;117}118119static VkResult120lvp_image_from_swapchain(VkDevice device,121const VkImageCreateInfo *pCreateInfo,122const VkImageSwapchainCreateInfoKHR *swapchain_info,123const VkAllocationCallbacks *pAllocator,124VkImage *pImage)125{126ASSERTED struct lvp_image *swapchain_image = lvp_swapchain_get_image(swapchain_info->swapchain, 0);127assert(swapchain_image);128129assert(swapchain_image->type == pCreateInfo->imageType);130131VkImageCreateInfo local_create_info;132local_create_info = *pCreateInfo;133local_create_info.pNext = NULL;134/* The following parameters are implictly selected by the wsi code. */135local_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;136local_create_info.samples = VK_SAMPLE_COUNT_1_BIT;137local_create_info.usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;138139assert(!(local_create_info.usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT));140return lvp_image_create(device,141&(struct lvp_image_create_info) {142.vk_info = &local_create_info,143},144pAllocator,145pImage);146}147148VKAPI_ATTR VkResult VKAPI_CALL149lvp_CreateImage(VkDevice device,150const VkImageCreateInfo *pCreateInfo,151const VkAllocationCallbacks *pAllocator,152VkImage *pImage)153{154const VkImageSwapchainCreateInfoKHR *swapchain_info =155vk_find_struct_const(pCreateInfo->pNext, IMAGE_SWAPCHAIN_CREATE_INFO_KHR);156if (swapchain_info && swapchain_info->swapchain != VK_NULL_HANDLE)157return lvp_image_from_swapchain(device, pCreateInfo, swapchain_info,158pAllocator, pImage);159return lvp_image_create(device,160&(struct lvp_image_create_info) {161.vk_info = pCreateInfo,162.bind_flags = 0,163},164pAllocator,165pImage);166}167168VKAPI_ATTR void VKAPI_CALL169lvp_DestroyImage(VkDevice _device, VkImage _image,170const VkAllocationCallbacks *pAllocator)171{172LVP_FROM_HANDLE(lvp_device, device, _device);173LVP_FROM_HANDLE(lvp_image, image, _image);174175if (!_image)176return;177pipe_resource_reference(&image->bo, NULL);178vk_object_base_finish(&image->base);179vk_free2(&device->vk.alloc, pAllocator, image);180}181182VKAPI_ATTR VkResult VKAPI_CALL183lvp_CreateImageView(VkDevice _device,184const VkImageViewCreateInfo *pCreateInfo,185const VkAllocationCallbacks *pAllocator,186VkImageView *pView)187{188LVP_FROM_HANDLE(lvp_device, device, _device);189LVP_FROM_HANDLE(lvp_image, image, pCreateInfo->image);190struct lvp_image_view *view;191192view = vk_alloc2(&device->vk.alloc, pAllocator, sizeof(*view), 8,193VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);194if (view == NULL)195return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);196197vk_object_base_init(&device->vk, &view->base,198VK_OBJECT_TYPE_IMAGE_VIEW);199view->view_type = pCreateInfo->viewType;200view->format = pCreateInfo->format;201view->pformat = lvp_vk_format_to_pipe_format(pCreateInfo->format);202view->components = pCreateInfo->components;203view->subresourceRange = pCreateInfo->subresourceRange;204view->image = image;205view->surface = NULL;206*pView = lvp_image_view_to_handle(view);207208return VK_SUCCESS;209}210211VKAPI_ATTR void VKAPI_CALL212lvp_DestroyImageView(VkDevice _device, VkImageView _iview,213const VkAllocationCallbacks *pAllocator)214{215LVP_FROM_HANDLE(lvp_device, device, _device);216LVP_FROM_HANDLE(lvp_image_view, iview, _iview);217218if (!_iview)219return;220221pipe_surface_reference(&iview->surface, NULL);222vk_object_base_finish(&iview->base);223vk_free2(&device->vk.alloc, pAllocator, iview);224}225226VKAPI_ATTR void VKAPI_CALL lvp_GetImageSubresourceLayout(227VkDevice _device,228VkImage _image,229const VkImageSubresource* pSubresource,230VkSubresourceLayout* pLayout)231{232LVP_FROM_HANDLE(lvp_device, device, _device);233LVP_FROM_HANDLE(lvp_image, image, _image);234uint64_t value;235236device->pscreen->resource_get_param(device->pscreen,237NULL,238image->bo,2390,240pSubresource->arrayLayer,241pSubresource->mipLevel,242PIPE_RESOURCE_PARAM_STRIDE,2430, &value);244245pLayout->rowPitch = value;246247device->pscreen->resource_get_param(device->pscreen,248NULL,249image->bo,2500,251pSubresource->arrayLayer,252pSubresource->mipLevel,253PIPE_RESOURCE_PARAM_OFFSET,2540, &value);255256pLayout->offset = value;257258device->pscreen->resource_get_param(device->pscreen,259NULL,260image->bo,2610,262pSubresource->arrayLayer,263pSubresource->mipLevel,264PIPE_RESOURCE_PARAM_LAYER_STRIDE,2650, &value);266267if (image->bo->target == PIPE_TEXTURE_3D) {268pLayout->depthPitch = value;269pLayout->arrayPitch = 0;270} else {271pLayout->depthPitch = 0;272pLayout->arrayPitch = value;273}274pLayout->size = image->size;275276switch (pSubresource->aspectMask) {277case VK_IMAGE_ASPECT_COLOR_BIT:278break;279case VK_IMAGE_ASPECT_DEPTH_BIT:280break;281case VK_IMAGE_ASPECT_STENCIL_BIT:282break;283default:284assert(!"Invalid image aspect");285}286}287288VKAPI_ATTR VkResult VKAPI_CALL lvp_CreateBuffer(289VkDevice _device,290const VkBufferCreateInfo* pCreateInfo,291const VkAllocationCallbacks* pAllocator,292VkBuffer* pBuffer)293{294LVP_FROM_HANDLE(lvp_device, device, _device);295struct lvp_buffer *buffer;296297assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO);298299/* gallium has max 32-bit buffer sizes */300if (pCreateInfo->size > UINT32_MAX)301return VK_ERROR_OUT_OF_DEVICE_MEMORY;302303buffer = vk_alloc2(&device->vk.alloc, pAllocator, sizeof(*buffer), 8,304VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);305if (buffer == NULL)306return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);307308vk_object_base_init(&device->vk, &buffer->base, VK_OBJECT_TYPE_BUFFER);309buffer->size = pCreateInfo->size;310buffer->usage = pCreateInfo->usage;311buffer->offset = 0;312313{314struct pipe_resource template;315memset(&template, 0, sizeof(struct pipe_resource));316317if (pCreateInfo->usage & VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT)318template.bind |= PIPE_BIND_CONSTANT_BUFFER;319320template.screen = device->pscreen;321template.target = PIPE_BUFFER;322template.format = PIPE_FORMAT_R8_UNORM;323template.width0 = buffer->size;324template.height0 = 1;325template.depth0 = 1;326template.array_size = 1;327if (buffer->usage & VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT)328template.bind |= PIPE_BIND_SAMPLER_VIEW;329if (buffer->usage & VK_BUFFER_USAGE_STORAGE_BUFFER_BIT)330template.bind |= PIPE_BIND_SHADER_BUFFER;331if (buffer->usage & VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT)332template.bind |= PIPE_BIND_SHADER_IMAGE;333template.flags = PIPE_RESOURCE_FLAG_DONT_OVER_ALLOCATE;334buffer->bo = device->pscreen->resource_create_unbacked(device->pscreen,335&template,336&buffer->total_size);337if (!buffer->bo) {338vk_free2(&device->vk.alloc, pAllocator, buffer);339return vk_error(device->instance, VK_ERROR_OUT_OF_DEVICE_MEMORY);340}341}342*pBuffer = lvp_buffer_to_handle(buffer);343344return VK_SUCCESS;345}346347VKAPI_ATTR void VKAPI_CALL lvp_DestroyBuffer(348VkDevice _device,349VkBuffer _buffer,350const VkAllocationCallbacks* pAllocator)351{352LVP_FROM_HANDLE(lvp_device, device, _device);353LVP_FROM_HANDLE(lvp_buffer, buffer, _buffer);354355if (!_buffer)356return;357358pipe_resource_reference(&buffer->bo, NULL);359vk_object_base_finish(&buffer->base);360vk_free2(&device->vk.alloc, pAllocator, buffer);361}362363VKAPI_ATTR VkDeviceAddress VKAPI_CALL lvp_GetBufferDeviceAddress(364VkDevice device,365const VkBufferDeviceAddressInfoKHR* pInfo)366{367LVP_FROM_HANDLE(lvp_buffer, buffer, pInfo->buffer);368369return (VkDeviceAddress)(uintptr_t)buffer->pmem;370}371372VKAPI_ATTR uint64_t VKAPI_CALL lvp_GetBufferOpaqueCaptureAddress(373VkDevice device,374const VkBufferDeviceAddressInfoKHR* pInfo)375{376return 0;377}378379VKAPI_ATTR uint64_t VKAPI_CALL lvp_GetDeviceMemoryOpaqueCaptureAddress(380VkDevice device,381const VkDeviceMemoryOpaqueCaptureAddressInfoKHR* pInfo)382{383return 0;384}385386VKAPI_ATTR VkResult VKAPI_CALL387lvp_CreateBufferView(VkDevice _device,388const VkBufferViewCreateInfo *pCreateInfo,389const VkAllocationCallbacks *pAllocator,390VkBufferView *pView)391{392LVP_FROM_HANDLE(lvp_device, device, _device);393LVP_FROM_HANDLE(lvp_buffer, buffer, pCreateInfo->buffer);394struct lvp_buffer_view *view;395view = vk_alloc2(&device->vk.alloc, pAllocator, sizeof(*view), 8,396VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);397if (!view)398return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);399400vk_object_base_init(&device->vk, &view->base,401VK_OBJECT_TYPE_BUFFER_VIEW);402view->buffer = buffer;403view->format = pCreateInfo->format;404view->pformat = lvp_vk_format_to_pipe_format(pCreateInfo->format);405view->offset = pCreateInfo->offset;406view->range = pCreateInfo->range;407*pView = lvp_buffer_view_to_handle(view);408409return VK_SUCCESS;410}411412VKAPI_ATTR void VKAPI_CALL413lvp_DestroyBufferView(VkDevice _device, VkBufferView bufferView,414const VkAllocationCallbacks *pAllocator)415{416LVP_FROM_HANDLE(lvp_device, device, _device);417LVP_FROM_HANDLE(lvp_buffer_view, view, bufferView);418419if (!bufferView)420return;421vk_object_base_finish(&view->base);422vk_free2(&device->vk.alloc, pAllocator, view);423}424425426