• 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 VkResult
lvp_image_create(VkDevice _device,const struct lvp_image_create_info * create_info,const VkAllocationCallbacks * alloc,VkImage * pImage)30 lvp_image_create(VkDevice _device,
31                  const struct lvp_image_create_info *create_info,
32                  const VkAllocationCallbacks* alloc,
33                  VkImage *pImage)
34 {
35    LVP_FROM_HANDLE(lvp_device, device, _device);
36    const VkImageCreateInfo *pCreateInfo = create_info->vk_info;
37    struct lvp_image *image;
38 
39    assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO);
40 
41    image = vk_zalloc2(&device->vk.alloc, alloc, sizeof(*image), 8,
42                        VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
43    if (image == NULL)
44       return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
45 
46    vk_object_base_init(&device->vk, &image->base, VK_OBJECT_TYPE_IMAGE);
47    image->alignment = 16;
48    image->type = pCreateInfo->imageType;
49    {
50       struct pipe_resource template;
51 
52       memset(&template, 0, sizeof(template));
53 
54       template.screen = device->pscreen;
55       switch (pCreateInfo->imageType) {
56       case VK_IMAGE_TYPE_1D:
57          template.target = pCreateInfo->arrayLayers > 1 ? PIPE_TEXTURE_1D_ARRAY : PIPE_TEXTURE_1D;
58          break;
59       default:
60       case VK_IMAGE_TYPE_2D:
61          template.target = pCreateInfo->arrayLayers > 1 ? PIPE_TEXTURE_2D_ARRAY : PIPE_TEXTURE_2D;
62          if (pCreateInfo->flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT)
63             template.target = pCreateInfo->arrayLayers == 6 ? PIPE_TEXTURE_CUBE : PIPE_TEXTURE_CUBE_ARRAY;
64          break;
65       case VK_IMAGE_TYPE_3D:
66          template.target = PIPE_TEXTURE_3D;
67          break;
68       }
69 
70       template.format = vk_format_to_pipe(pCreateInfo->format);
71       template.width0 = pCreateInfo->extent.width;
72       template.height0 = pCreateInfo->extent.height;
73       template.depth0 = pCreateInfo->extent.depth;
74       template.array_size = pCreateInfo->arrayLayers;
75       template.last_level = pCreateInfo->mipLevels - 1;
76       template.nr_samples = pCreateInfo->samples;
77       template.nr_storage_samples = pCreateInfo->samples;
78       if (create_info->bind_flags)
79          template.bind = create_info->bind_flags;
80       image->bo = device->pscreen->resource_create_unbacked(device->pscreen,
81                                                             &template,
82                                                             &image->size);
83    }
84    *pImage = lvp_image_to_handle(image);
85 
86    return VK_SUCCESS;
87 }
88 
89 VkResult
lvp_CreateImage(VkDevice device,const VkImageCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkImage * pImage)90 lvp_CreateImage(VkDevice device,
91                 const VkImageCreateInfo *pCreateInfo,
92                 const VkAllocationCallbacks *pAllocator,
93                 VkImage *pImage)
94 {
95    return lvp_image_create(device,
96       &(struct lvp_image_create_info) {
97          .vk_info = pCreateInfo,
98          .bind_flags = 0,
99       },
100       pAllocator,
101       pImage);
102 }
103 
104 void
lvp_DestroyImage(VkDevice _device,VkImage _image,const VkAllocationCallbacks * pAllocator)105 lvp_DestroyImage(VkDevice _device, VkImage _image,
106                  const VkAllocationCallbacks *pAllocator)
107 {
108    LVP_FROM_HANDLE(lvp_device, device, _device);
109    LVP_FROM_HANDLE(lvp_image, image, _image);
110 
111    if (!_image)
112      return;
113    pipe_resource_reference(&image->bo, NULL);
114    vk_object_base_finish(&image->base);
115    vk_free2(&device->vk.alloc, pAllocator, image);
116 }
117 
118 VkResult
lvp_CreateImageView(VkDevice _device,const VkImageViewCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkImageView * pView)119 lvp_CreateImageView(VkDevice _device,
120                     const VkImageViewCreateInfo *pCreateInfo,
121                     const VkAllocationCallbacks *pAllocator,
122                     VkImageView *pView)
123 {
124    LVP_FROM_HANDLE(lvp_device, device, _device);
125    LVP_FROM_HANDLE(lvp_image, image, pCreateInfo->image);
126    struct lvp_image_view *view;
127 
128    view = vk_alloc2(&device->vk.alloc, pAllocator, sizeof(*view), 8,
129                      VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
130    if (view == NULL)
131       return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
132 
133    vk_object_base_init(&device->vk, &view->base,
134                        VK_OBJECT_TYPE_IMAGE_VIEW);
135    view->view_type = pCreateInfo->viewType;
136    view->format = pCreateInfo->format;
137    view->pformat = vk_format_to_pipe(pCreateInfo->format);
138    view->components = pCreateInfo->components;
139    view->subresourceRange = pCreateInfo->subresourceRange;
140    view->image = image;
141    view->surface = NULL;
142    *pView = lvp_image_view_to_handle(view);
143 
144    return VK_SUCCESS;
145 }
146 
147 void
lvp_DestroyImageView(VkDevice _device,VkImageView _iview,const VkAllocationCallbacks * pAllocator)148 lvp_DestroyImageView(VkDevice _device, VkImageView _iview,
149                      const VkAllocationCallbacks *pAllocator)
150 {
151    LVP_FROM_HANDLE(lvp_device, device, _device);
152    LVP_FROM_HANDLE(lvp_image_view, iview, _iview);
153 
154    if (!_iview)
155      return;
156 
157    pipe_surface_reference(&iview->surface, NULL);
158    vk_object_base_finish(&iview->base);
159    vk_free2(&device->vk.alloc, pAllocator, iview);
160 }
161 
lvp_GetImageSubresourceLayout(VkDevice _device,VkImage _image,const VkImageSubresource * pSubresource,VkSubresourceLayout * pLayout)162 void lvp_GetImageSubresourceLayout(
163     VkDevice                                    _device,
164     VkImage                                     _image,
165     const VkImageSubresource*                   pSubresource,
166     VkSubresourceLayout*                        pLayout)
167 {
168    LVP_FROM_HANDLE(lvp_device, device, _device);
169    LVP_FROM_HANDLE(lvp_image, image, _image);
170    uint64_t value;
171 
172    device->pscreen->resource_get_param(device->pscreen,
173                                        NULL,
174                                        image->bo,
175                                        0,
176                                        pSubresource->arrayLayer,
177                                        pSubresource->mipLevel,
178                                        PIPE_RESOURCE_PARAM_STRIDE,
179                                        0, &value);
180 
181    pLayout->rowPitch = value;
182 
183    device->pscreen->resource_get_param(device->pscreen,
184                                        NULL,
185                                        image->bo,
186                                        0,
187                                        pSubresource->arrayLayer,
188                                        pSubresource->mipLevel,
189                                        PIPE_RESOURCE_PARAM_OFFSET,
190                                        0, &value);
191 
192    pLayout->offset = value;
193 
194    device->pscreen->resource_get_param(device->pscreen,
195                                        NULL,
196                                        image->bo,
197                                        0,
198                                        pSubresource->arrayLayer,
199                                        pSubresource->mipLevel,
200                                        PIPE_RESOURCE_PARAM_LAYER_STRIDE,
201                                        0, &value);
202 
203    if (image->bo->target == PIPE_TEXTURE_3D) {
204       pLayout->depthPitch = value;
205       pLayout->arrayPitch = 0;
206    } else {
207       pLayout->depthPitch = 0;
208       pLayout->arrayPitch = value;
209    }
210    pLayout->size = image->size;
211 
212    switch (pSubresource->aspectMask) {
213    case VK_IMAGE_ASPECT_COLOR_BIT:
214       break;
215    case VK_IMAGE_ASPECT_DEPTH_BIT:
216       break;
217    case VK_IMAGE_ASPECT_STENCIL_BIT:
218       break;
219    default:
220       assert(!"Invalid image aspect");
221    }
222 }
223 
lvp_CreateBuffer(VkDevice _device,const VkBufferCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkBuffer * pBuffer)224 VkResult lvp_CreateBuffer(
225     VkDevice                                    _device,
226     const VkBufferCreateInfo*                   pCreateInfo,
227     const VkAllocationCallbacks*                pAllocator,
228     VkBuffer*                                   pBuffer)
229 {
230    LVP_FROM_HANDLE(lvp_device, device, _device);
231    struct lvp_buffer *buffer;
232 
233    assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO);
234 
235    /* gallium has max 32-bit buffer sizes */
236    if (pCreateInfo->size > UINT32_MAX)
237       return VK_ERROR_OUT_OF_DEVICE_MEMORY;
238 
239    buffer = vk_alloc2(&device->vk.alloc, pAllocator, sizeof(*buffer), 8,
240                        VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
241    if (buffer == NULL)
242       return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
243 
244    vk_object_base_init(&device->vk, &buffer->base, VK_OBJECT_TYPE_BUFFER);
245    buffer->size = pCreateInfo->size;
246    buffer->usage = pCreateInfo->usage;
247    buffer->offset = 0;
248 
249    {
250       struct pipe_resource template;
251       memset(&template, 0, sizeof(struct pipe_resource));
252       template.screen = device->pscreen;
253       template.target = PIPE_BUFFER;
254       template.format = PIPE_FORMAT_R8_UNORM;
255       template.width0 = buffer->size;
256       template.height0 = 1;
257       template.depth0 = 1;
258       template.array_size = 1;
259       template.flags = PIPE_RESOURCE_FLAG_DONT_OVER_ALLOCATE;
260       buffer->bo = device->pscreen->resource_create_unbacked(device->pscreen,
261                                                              &template,
262                                                              &buffer->total_size);
263       if (!buffer->bo) {
264          vk_free2(&device->vk.alloc, pAllocator, buffer);
265          return vk_error(device->instance, VK_ERROR_OUT_OF_DEVICE_MEMORY);
266       }
267    }
268    *pBuffer = lvp_buffer_to_handle(buffer);
269 
270    return VK_SUCCESS;
271 }
272 
lvp_DestroyBuffer(VkDevice _device,VkBuffer _buffer,const VkAllocationCallbacks * pAllocator)273 void lvp_DestroyBuffer(
274     VkDevice                                    _device,
275     VkBuffer                                    _buffer,
276     const VkAllocationCallbacks*                pAllocator)
277 {
278    LVP_FROM_HANDLE(lvp_device, device, _device);
279    LVP_FROM_HANDLE(lvp_buffer, buffer, _buffer);
280 
281    if (!_buffer)
282      return;
283 
284    pipe_resource_reference(&buffer->bo, NULL);
285    vk_object_base_finish(&buffer->base);
286    vk_free2(&device->vk.alloc, pAllocator, buffer);
287 }
288 
289 VkResult
lvp_CreateBufferView(VkDevice _device,const VkBufferViewCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkBufferView * pView)290 lvp_CreateBufferView(VkDevice _device,
291                      const VkBufferViewCreateInfo *pCreateInfo,
292                      const VkAllocationCallbacks *pAllocator,
293                      VkBufferView *pView)
294 {
295    LVP_FROM_HANDLE(lvp_device, device, _device);
296    LVP_FROM_HANDLE(lvp_buffer, buffer, pCreateInfo->buffer);
297    struct lvp_buffer_view *view;
298    view = vk_alloc2(&device->vk.alloc, pAllocator, sizeof(*view), 8,
299                      VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
300    if (!view)
301       return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
302 
303    vk_object_base_init(&device->vk, &view->base,
304                        VK_OBJECT_TYPE_BUFFER_VIEW);
305    view->buffer = buffer;
306    view->format = pCreateInfo->format;
307    view->pformat = vk_format_to_pipe(pCreateInfo->format);
308    view->offset = pCreateInfo->offset;
309    view->range = pCreateInfo->range;
310    *pView = lvp_buffer_view_to_handle(view);
311 
312    return VK_SUCCESS;
313 }
314 
315 void
lvp_DestroyBufferView(VkDevice _device,VkBufferView bufferView,const VkAllocationCallbacks * pAllocator)316 lvp_DestroyBufferView(VkDevice _device, VkBufferView bufferView,
317                       const VkAllocationCallbacks *pAllocator)
318 {
319    LVP_FROM_HANDLE(lvp_device, device, _device);
320    LVP_FROM_HANDLE(lvp_buffer_view, view, bufferView);
321 
322    if (!bufferView)
323      return;
324    vk_object_base_finish(&view->base);
325    vk_free2(&device->vk.alloc, pAllocator, view);
326 }
327