vallium: limit buffer allocations to gallium max.
[mesa.git] / src / gallium / frontends / vallium / val_image.c
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 "val_private.h"
25 #include "util/format/u_format.h"
26 #include "util/u_inlines.h"
27 #include "pipe/p_state.h"
28
29 VkResult
30 val_image_create(VkDevice _device,
31 const struct val_image_create_info *create_info,
32 const VkAllocationCallbacks* alloc,
33 VkImage *pImage)
34 {
35 VAL_FROM_HANDLE(val_device, device, _device);
36 const VkImageCreateInfo *pCreateInfo = create_info->vk_info;
37 struct val_image *image;
38
39 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO);
40
41 image = vk_zalloc2(&device->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 = val_image_to_handle(image);
85
86 return VK_SUCCESS;
87 }
88
89 VkResult
90 val_CreateImage(VkDevice device,
91 const VkImageCreateInfo *pCreateInfo,
92 const VkAllocationCallbacks *pAllocator,
93 VkImage *pImage)
94 {
95 return val_image_create(device,
96 &(struct val_image_create_info) {
97 .vk_info = pCreateInfo,
98 .bind_flags = 0,
99 },
100 pAllocator,
101 pImage);
102 }
103
104 void
105 val_DestroyImage(VkDevice _device, VkImage _image,
106 const VkAllocationCallbacks *pAllocator)
107 {
108 VAL_FROM_HANDLE(val_device, device, _device);
109 VAL_FROM_HANDLE(val_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->alloc, pAllocator, image);
116 }
117
118 VkResult
119 val_CreateImageView(VkDevice _device,
120 const VkImageViewCreateInfo *pCreateInfo,
121 const VkAllocationCallbacks *pAllocator,
122 VkImageView *pView)
123 {
124 VAL_FROM_HANDLE(val_device, device, _device);
125 VAL_FROM_HANDLE(val_image, image, pCreateInfo->image);
126 struct val_image_view *view;
127
128 view = vk_alloc2(&device->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 = val_image_view_to_handle(view);
143
144 return VK_SUCCESS;
145 }
146
147 void
148 val_DestroyImageView(VkDevice _device, VkImageView _iview,
149 const VkAllocationCallbacks *pAllocator)
150 {
151 VAL_FROM_HANDLE(val_device, device, _device);
152 VAL_FROM_HANDLE(val_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->alloc, pAllocator, iview);
160 }
161
162 void val_GetImageSubresourceLayout(
163 VkDevice _device,
164 VkImage _image,
165 const VkImageSubresource* pSubresource,
166 VkSubresourceLayout* pLayout)
167 {
168 VAL_FROM_HANDLE(val_device, device, _device);
169 VAL_FROM_HANDLE(val_image, image, _image);
170 uint32_t stride, offset;
171 device->pscreen->resource_get_info(device->pscreen,
172 image->bo,
173 &stride, &offset);
174 pLayout->offset = offset;
175 pLayout->rowPitch = stride;
176 pLayout->arrayPitch = 0;
177 pLayout->size = image->size;
178 switch (pSubresource->aspectMask) {
179 case VK_IMAGE_ASPECT_COLOR_BIT:
180 break;
181 case VK_IMAGE_ASPECT_DEPTH_BIT:
182 break;
183 case VK_IMAGE_ASPECT_STENCIL_BIT:
184 break;
185 default:
186 assert(!"Invalid image aspect");
187 }
188 }
189
190 VkResult val_CreateBuffer(
191 VkDevice _device,
192 const VkBufferCreateInfo* pCreateInfo,
193 const VkAllocationCallbacks* pAllocator,
194 VkBuffer* pBuffer)
195 {
196 VAL_FROM_HANDLE(val_device, device, _device);
197 struct val_buffer *buffer;
198
199 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO);
200
201 /* gallium has max 32-bit buffer sizes */
202 if (pCreateInfo->size > UINT32_MAX)
203 return VK_ERROR_OUT_OF_DEVICE_MEMORY;
204
205 buffer = vk_alloc2(&device->alloc, pAllocator, sizeof(*buffer), 8,
206 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
207 if (buffer == NULL)
208 return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
209
210 vk_object_base_init(&device->vk, &buffer->base, VK_OBJECT_TYPE_BUFFER);
211 buffer->size = pCreateInfo->size;
212 buffer->usage = pCreateInfo->usage;
213 buffer->offset = 0;
214
215 {
216 struct pipe_resource template;
217 memset(&template, 0, sizeof(struct pipe_resource));
218 template.screen = device->pscreen;
219 template.target = PIPE_BUFFER;
220 template.format = PIPE_FORMAT_R8_UNORM;
221 template.width0 = buffer->size;
222 template.height0 = 1;
223 template.depth0 = 1;
224 template.array_size = 1;
225 template.flags = PIPE_RESOURCE_FLAG_DONT_OVER_ALLOCATE;
226 buffer->bo = device->pscreen->resource_create_unbacked(device->pscreen,
227 &template,
228 &buffer->total_size);
229 if (!buffer->bo) {
230 vk_free2(&device->alloc, pAllocator, buffer);
231 return vk_error(device->instance, VK_ERROR_OUT_OF_DEVICE_MEMORY);
232 }
233 }
234 *pBuffer = val_buffer_to_handle(buffer);
235
236 return VK_SUCCESS;
237 }
238
239 void val_DestroyBuffer(
240 VkDevice _device,
241 VkBuffer _buffer,
242 const VkAllocationCallbacks* pAllocator)
243 {
244 VAL_FROM_HANDLE(val_device, device, _device);
245 VAL_FROM_HANDLE(val_buffer, buffer, _buffer);
246
247 if (!_buffer)
248 return;
249
250 pipe_resource_reference(&buffer->bo, NULL);
251 vk_object_base_finish(&buffer->base);
252 vk_free2(&device->alloc, pAllocator, buffer);
253 }
254
255 VkResult
256 val_CreateBufferView(VkDevice _device,
257 const VkBufferViewCreateInfo *pCreateInfo,
258 const VkAllocationCallbacks *pAllocator,
259 VkBufferView *pView)
260 {
261 VAL_FROM_HANDLE(val_device, device, _device);
262 VAL_FROM_HANDLE(val_buffer, buffer, pCreateInfo->buffer);
263 struct val_buffer_view *view;
264 view = vk_alloc2(&device->alloc, pAllocator, sizeof(*view), 8,
265 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
266 if (!view)
267 return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
268
269 vk_object_base_init(&device->vk, &view->base,
270 VK_OBJECT_TYPE_BUFFER_VIEW);
271 view->buffer = buffer;
272 view->format = pCreateInfo->format;
273 view->pformat = vk_format_to_pipe(pCreateInfo->format);
274 view->offset = pCreateInfo->offset;
275 view->range = pCreateInfo->range;
276 *pView = val_buffer_view_to_handle(view);
277
278 return VK_SUCCESS;
279 }
280
281 void
282 val_DestroyBufferView(VkDevice _device, VkBufferView bufferView,
283 const VkAllocationCallbacks *pAllocator)
284 {
285 VAL_FROM_HANDLE(val_device, device, _device);
286 VAL_FROM_HANDLE(val_buffer_view, view, bufferView);
287
288 if (!bufferView)
289 return;
290 vk_object_base_finish(&view->base);
291 vk_free2(&device->alloc, pAllocator, view);
292 }