• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2019 Red Hat.
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 "lvp_private.h"
25 #include "util/format/u_format.h"
26 #include "util/u_inlines.h"
27 #include "pipe/p_state.h"
28 
29 static VkResult
lvp_image_create(VkDevice _device,const VkImageCreateInfo * pCreateInfo,const VkAllocationCallbacks * alloc,VkImage * pImage)30 lvp_image_create(VkDevice _device,
31                  const VkImageCreateInfo *pCreateInfo,
32                  const VkAllocationCallbacks* alloc,
33                  VkImage *pImage)
34 {
35    LVP_FROM_HANDLE(lvp_device, device, _device);
36    struct lvp_image *image;
37 
38    assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO);
39 
40    image = vk_image_create(&device->vk, pCreateInfo, alloc, sizeof(*image));
41    if (image == NULL)
42       return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
43 
44    image->alignment = 16;
45    {
46       struct pipe_resource template;
47 
48       memset(&template, 0, sizeof(template));
49 
50       template.screen = device->pscreen;
51       switch (pCreateInfo->imageType) {
52       case VK_IMAGE_TYPE_1D:
53          template.target = pCreateInfo->arrayLayers > 1 ? PIPE_TEXTURE_1D_ARRAY : PIPE_TEXTURE_1D;
54          break;
55       default:
56       case VK_IMAGE_TYPE_2D:
57          template.target = pCreateInfo->arrayLayers > 1 ? PIPE_TEXTURE_2D_ARRAY : PIPE_TEXTURE_2D;
58          break;
59       case VK_IMAGE_TYPE_3D:
60          template.target = PIPE_TEXTURE_3D;
61          break;
62       }
63 
64       template.format = lvp_vk_format_to_pipe_format(pCreateInfo->format);
65 
66       bool is_ds = util_format_is_depth_or_stencil(template.format);
67 
68       if (pCreateInfo->usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) {
69          template.bind |= PIPE_BIND_RENDER_TARGET;
70          /* sampler view is needed for resolve blits */
71          if (pCreateInfo->samples > 1)
72             template.bind |= PIPE_BIND_SAMPLER_VIEW;
73       }
74 
75       if (pCreateInfo->usage & VK_IMAGE_USAGE_TRANSFER_DST_BIT) {
76          if (!is_ds)
77             template.bind |= PIPE_BIND_RENDER_TARGET;
78          else
79             template.bind |= PIPE_BIND_DEPTH_STENCIL;
80       }
81 
82       if (pCreateInfo->usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)
83          template.bind |= PIPE_BIND_DEPTH_STENCIL;
84 
85       if (pCreateInfo->usage & (VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
86                                 VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT))
87          template.bind |= PIPE_BIND_SAMPLER_VIEW;
88 
89       if (pCreateInfo->usage & VK_IMAGE_USAGE_STORAGE_BIT)
90          template.bind |= PIPE_BIND_SHADER_IMAGE;
91 
92       template.width0 = pCreateInfo->extent.width;
93       template.height0 = pCreateInfo->extent.height;
94       template.depth0 = pCreateInfo->extent.depth;
95       template.array_size = pCreateInfo->arrayLayers;
96       template.last_level = pCreateInfo->mipLevels - 1;
97       template.nr_samples = pCreateInfo->samples;
98       template.nr_storage_samples = pCreateInfo->samples;
99       image->bo = device->pscreen->resource_create_unbacked(device->pscreen,
100                                                             &template,
101                                                             &image->size);
102       if (!image->bo)
103          return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
104    }
105    *pImage = lvp_image_to_handle(image);
106 
107    return VK_SUCCESS;
108 }
109 
110 struct lvp_image *
lvp_swapchain_get_image(VkSwapchainKHR swapchain,uint32_t index)111 lvp_swapchain_get_image(VkSwapchainKHR swapchain,
112                         uint32_t index)
113 {
114    VkImage image = wsi_common_get_image(swapchain, index);
115    return lvp_image_from_handle(image);
116 }
117 
118 static VkResult
lvp_image_from_swapchain(VkDevice device,const VkImageCreateInfo * pCreateInfo,const VkImageSwapchainCreateInfoKHR * swapchain_info,const VkAllocationCallbacks * pAllocator,VkImage * pImage)119 lvp_image_from_swapchain(VkDevice device,
120                          const VkImageCreateInfo *pCreateInfo,
121                          const VkImageSwapchainCreateInfoKHR *swapchain_info,
122                          const VkAllocationCallbacks *pAllocator,
123                          VkImage *pImage)
124 {
125    ASSERTED struct lvp_image *swapchain_image = lvp_swapchain_get_image(swapchain_info->swapchain, 0);
126    assert(swapchain_image);
127 
128    assert(swapchain_image->vk.image_type == pCreateInfo->imageType);
129 
130    VkImageCreateInfo local_create_info;
131    local_create_info = *pCreateInfo;
132    local_create_info.pNext = NULL;
133    /* The following parameters are implictly selected by the wsi code. */
134    local_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
135    local_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
136    local_create_info.usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
137 
138    assert(!(local_create_info.usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT));
139    return lvp_image_create(device, &local_create_info, pAllocator,
140                            pImage);
141 }
142 
143 VKAPI_ATTR VkResult VKAPI_CALL
lvp_CreateImage(VkDevice device,const VkImageCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkImage * pImage)144 lvp_CreateImage(VkDevice device,
145                 const VkImageCreateInfo *pCreateInfo,
146                 const VkAllocationCallbacks *pAllocator,
147                 VkImage *pImage)
148 {
149    const VkImageSwapchainCreateInfoKHR *swapchain_info =
150       vk_find_struct_const(pCreateInfo->pNext, IMAGE_SWAPCHAIN_CREATE_INFO_KHR);
151    if (swapchain_info && swapchain_info->swapchain != VK_NULL_HANDLE)
152       return lvp_image_from_swapchain(device, pCreateInfo, swapchain_info,
153                                       pAllocator, pImage);
154    return lvp_image_create(device, pCreateInfo, pAllocator,
155                            pImage);
156 }
157 
158 VKAPI_ATTR void VKAPI_CALL
lvp_DestroyImage(VkDevice _device,VkImage _image,const VkAllocationCallbacks * pAllocator)159 lvp_DestroyImage(VkDevice _device, VkImage _image,
160                  const VkAllocationCallbacks *pAllocator)
161 {
162    LVP_FROM_HANDLE(lvp_device, device, _device);
163    LVP_FROM_HANDLE(lvp_image, image, _image);
164 
165    if (!_image)
166      return;
167    pipe_resource_reference(&image->bo, NULL);
168    vk_image_destroy(&device->vk, pAllocator, &image->vk);
169 }
170 
171 VKAPI_ATTR VkResult VKAPI_CALL
lvp_CreateImageView(VkDevice _device,const VkImageViewCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkImageView * pView)172 lvp_CreateImageView(VkDevice _device,
173                     const VkImageViewCreateInfo *pCreateInfo,
174                     const VkAllocationCallbacks *pAllocator,
175                     VkImageView *pView)
176 {
177    LVP_FROM_HANDLE(lvp_device, device, _device);
178    LVP_FROM_HANDLE(lvp_image, image, pCreateInfo->image);
179    struct lvp_image_view *view;
180 
181    view = vk_image_view_create(&device->vk, false, pCreateInfo,
182                                pAllocator, sizeof(*view));
183    if (view == NULL)
184       return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
185 
186    view->pformat = lvp_vk_format_to_pipe_format(view->vk.format);
187    view->image = image;
188    view->surface = NULL;
189    *pView = lvp_image_view_to_handle(view);
190 
191    return VK_SUCCESS;
192 }
193 
194 VKAPI_ATTR void VKAPI_CALL
lvp_DestroyImageView(VkDevice _device,VkImageView _iview,const VkAllocationCallbacks * pAllocator)195 lvp_DestroyImageView(VkDevice _device, VkImageView _iview,
196                      const VkAllocationCallbacks *pAllocator)
197 {
198    LVP_FROM_HANDLE(lvp_device, device, _device);
199    LVP_FROM_HANDLE(lvp_image_view, iview, _iview);
200 
201    if (!_iview)
202      return;
203 
204    pipe_surface_reference(&iview->surface, NULL);
205    vk_image_view_destroy(&device->vk, pAllocator, &iview->vk);
206 }
207 
lvp_GetImageSubresourceLayout(VkDevice _device,VkImage _image,const VkImageSubresource * pSubresource,VkSubresourceLayout * pLayout)208 VKAPI_ATTR void VKAPI_CALL lvp_GetImageSubresourceLayout(
209     VkDevice                                    _device,
210     VkImage                                     _image,
211     const VkImageSubresource*                   pSubresource,
212     VkSubresourceLayout*                        pLayout)
213 {
214    LVP_FROM_HANDLE(lvp_device, device, _device);
215    LVP_FROM_HANDLE(lvp_image, image, _image);
216    uint64_t value;
217 
218    device->pscreen->resource_get_param(device->pscreen,
219                                        NULL,
220                                        image->bo,
221                                        0,
222                                        pSubresource->arrayLayer,
223                                        pSubresource->mipLevel,
224                                        PIPE_RESOURCE_PARAM_STRIDE,
225                                        0, &value);
226 
227    pLayout->rowPitch = value;
228 
229    device->pscreen->resource_get_param(device->pscreen,
230                                        NULL,
231                                        image->bo,
232                                        0,
233                                        pSubresource->arrayLayer,
234                                        pSubresource->mipLevel,
235                                        PIPE_RESOURCE_PARAM_OFFSET,
236                                        0, &value);
237 
238    pLayout->offset = value;
239 
240    device->pscreen->resource_get_param(device->pscreen,
241                                        NULL,
242                                        image->bo,
243                                        0,
244                                        pSubresource->arrayLayer,
245                                        pSubresource->mipLevel,
246                                        PIPE_RESOURCE_PARAM_LAYER_STRIDE,
247                                        0, &value);
248 
249    if (image->bo->target == PIPE_TEXTURE_3D) {
250       pLayout->depthPitch = value;
251       pLayout->arrayPitch = 0;
252    } else {
253       pLayout->depthPitch = 0;
254       pLayout->arrayPitch = value;
255    }
256    pLayout->size = image->size;
257 
258    switch (pSubresource->aspectMask) {
259    case VK_IMAGE_ASPECT_COLOR_BIT:
260       break;
261    case VK_IMAGE_ASPECT_DEPTH_BIT:
262       break;
263    case VK_IMAGE_ASPECT_STENCIL_BIT:
264       break;
265    default:
266       assert(!"Invalid image aspect");
267    }
268 }
269 
lvp_CreateBuffer(VkDevice _device,const VkBufferCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkBuffer * pBuffer)270 VKAPI_ATTR VkResult VKAPI_CALL lvp_CreateBuffer(
271     VkDevice                                    _device,
272     const VkBufferCreateInfo*                   pCreateInfo,
273     const VkAllocationCallbacks*                pAllocator,
274     VkBuffer*                                   pBuffer)
275 {
276    LVP_FROM_HANDLE(lvp_device, device, _device);
277    struct lvp_buffer *buffer;
278 
279    assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO);
280 
281    /* gallium has max 32-bit buffer sizes */
282    if (pCreateInfo->size > UINT32_MAX)
283       return VK_ERROR_OUT_OF_DEVICE_MEMORY;
284 
285    buffer = vk_alloc2(&device->vk.alloc, pAllocator, sizeof(*buffer), 8,
286                        VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
287    if (buffer == NULL)
288       return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
289 
290    vk_object_base_init(&device->vk, &buffer->base, VK_OBJECT_TYPE_BUFFER);
291    buffer->size = pCreateInfo->size;
292    buffer->usage = pCreateInfo->usage;
293    buffer->offset = 0;
294 
295    {
296       struct pipe_resource template;
297       memset(&template, 0, sizeof(struct pipe_resource));
298 
299       if (pCreateInfo->usage & VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT)
300          template.bind |= PIPE_BIND_CONSTANT_BUFFER;
301 
302       template.screen = device->pscreen;
303       template.target = PIPE_BUFFER;
304       template.format = PIPE_FORMAT_R8_UNORM;
305       template.width0 = buffer->size;
306       template.height0 = 1;
307       template.depth0 = 1;
308       template.array_size = 1;
309       if (buffer->usage & VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT)
310          template.bind |= PIPE_BIND_SAMPLER_VIEW;
311       if (buffer->usage & VK_BUFFER_USAGE_STORAGE_BUFFER_BIT)
312          template.bind |= PIPE_BIND_SHADER_BUFFER;
313       if (buffer->usage & VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT)
314          template.bind |= PIPE_BIND_SHADER_IMAGE;
315       template.flags = PIPE_RESOURCE_FLAG_DONT_OVER_ALLOCATE;
316       buffer->bo = device->pscreen->resource_create_unbacked(device->pscreen,
317                                                              &template,
318                                                              &buffer->total_size);
319       if (!buffer->bo) {
320          vk_free2(&device->vk.alloc, pAllocator, buffer);
321          return vk_error(device, VK_ERROR_OUT_OF_DEVICE_MEMORY);
322       }
323    }
324    *pBuffer = lvp_buffer_to_handle(buffer);
325 
326    return VK_SUCCESS;
327 }
328 
lvp_DestroyBuffer(VkDevice _device,VkBuffer _buffer,const VkAllocationCallbacks * pAllocator)329 VKAPI_ATTR void VKAPI_CALL lvp_DestroyBuffer(
330     VkDevice                                    _device,
331     VkBuffer                                    _buffer,
332     const VkAllocationCallbacks*                pAllocator)
333 {
334    LVP_FROM_HANDLE(lvp_device, device, _device);
335    LVP_FROM_HANDLE(lvp_buffer, buffer, _buffer);
336 
337    if (!_buffer)
338      return;
339 
340    pipe_resource_reference(&buffer->bo, NULL);
341    vk_object_base_finish(&buffer->base);
342    vk_free2(&device->vk.alloc, pAllocator, buffer);
343 }
344 
lvp_GetBufferDeviceAddress(VkDevice device,const VkBufferDeviceAddressInfo * pInfo)345 VKAPI_ATTR VkDeviceAddress VKAPI_CALL lvp_GetBufferDeviceAddress(
346    VkDevice                                    device,
347    const VkBufferDeviceAddressInfo*            pInfo)
348 {
349    LVP_FROM_HANDLE(lvp_buffer, buffer, pInfo->buffer);
350 
351    return (VkDeviceAddress)(uintptr_t)buffer->pmem;
352 }
353 
lvp_GetBufferOpaqueCaptureAddress(VkDevice device,const VkBufferDeviceAddressInfo * pInfo)354 VKAPI_ATTR uint64_t VKAPI_CALL lvp_GetBufferOpaqueCaptureAddress(
355     VkDevice                                    device,
356     const VkBufferDeviceAddressInfo*            pInfo)
357 {
358    return 0;
359 }
360 
lvp_GetDeviceMemoryOpaqueCaptureAddress(VkDevice device,const VkDeviceMemoryOpaqueCaptureAddressInfo * pInfo)361 VKAPI_ATTR uint64_t VKAPI_CALL lvp_GetDeviceMemoryOpaqueCaptureAddress(
362     VkDevice                                    device,
363     const VkDeviceMemoryOpaqueCaptureAddressInfo* pInfo)
364 {
365    return 0;
366 }
367 
368 VKAPI_ATTR VkResult VKAPI_CALL
lvp_CreateBufferView(VkDevice _device,const VkBufferViewCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkBufferView * pView)369 lvp_CreateBufferView(VkDevice _device,
370                      const VkBufferViewCreateInfo *pCreateInfo,
371                      const VkAllocationCallbacks *pAllocator,
372                      VkBufferView *pView)
373 {
374    LVP_FROM_HANDLE(lvp_device, device, _device);
375    LVP_FROM_HANDLE(lvp_buffer, buffer, pCreateInfo->buffer);
376    struct lvp_buffer_view *view;
377    view = vk_alloc2(&device->vk.alloc, pAllocator, sizeof(*view), 8,
378                      VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
379    if (!view)
380       return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
381 
382    vk_object_base_init(&device->vk, &view->base,
383                        VK_OBJECT_TYPE_BUFFER_VIEW);
384    view->buffer = buffer;
385    view->format = pCreateInfo->format;
386    view->pformat = lvp_vk_format_to_pipe_format(pCreateInfo->format);
387    view->offset = pCreateInfo->offset;
388    view->range = pCreateInfo->range;
389    *pView = lvp_buffer_view_to_handle(view);
390 
391    return VK_SUCCESS;
392 }
393 
394 VKAPI_ATTR void VKAPI_CALL
lvp_DestroyBufferView(VkDevice _device,VkBufferView bufferView,const VkAllocationCallbacks * pAllocator)395 lvp_DestroyBufferView(VkDevice _device, VkBufferView bufferView,
396                       const VkAllocationCallbacks *pAllocator)
397 {
398    LVP_FROM_HANDLE(lvp_device, device, _device);
399    LVP_FROM_HANDLE(lvp_buffer_view, view, bufferView);
400 
401    if (!bufferView)
402      return;
403    vk_object_base_finish(&view->base);
404    vk_free2(&device->vk.alloc, pAllocator, view);
405 }
406