29a493e77fe2374e9aa9d518f66c4f56488e089f
[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 buffer = vk_alloc2(&device->alloc, pAllocator, sizeof(*buffer), 8,
202 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
203 if (buffer == NULL)
204 return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
205
206 vk_object_base_init(&device->vk, &buffer->base, VK_OBJECT_TYPE_BUFFER);
207 buffer->size = pCreateInfo->size;
208 buffer->usage = pCreateInfo->usage;
209 buffer->offset = 0;
210
211 {
212 struct pipe_resource template;
213 memset(&template, 0, sizeof(struct pipe_resource));
214 template.screen = device->pscreen;
215 template.target = PIPE_BUFFER;
216 template.format = PIPE_FORMAT_R8_UNORM;
217 template.width0 = buffer->size;
218 template.height0 = 1;
219 template.depth0 = 1;
220 template.array_size = 1;
221 template.flags = PIPE_RESOURCE_FLAG_DONT_OVER_ALLOCATE;
222 buffer->bo = device->pscreen->resource_create_unbacked(device->pscreen,
223 &template,
224 &buffer->total_size);
225 if (!buffer->bo) {
226 vk_free2(&device->alloc, pAllocator, buffer);
227 return vk_error(device->instance, VK_ERROR_OUT_OF_DEVICE_MEMORY);
228 }
229 }
230 *pBuffer = val_buffer_to_handle(buffer);
231
232 return VK_SUCCESS;
233 }
234
235 void val_DestroyBuffer(
236 VkDevice _device,
237 VkBuffer _buffer,
238 const VkAllocationCallbacks* pAllocator)
239 {
240 VAL_FROM_HANDLE(val_device, device, _device);
241 VAL_FROM_HANDLE(val_buffer, buffer, _buffer);
242
243 if (!_buffer)
244 return;
245
246 pipe_resource_reference(&buffer->bo, NULL);
247 vk_object_base_finish(&buffer->base);
248 vk_free2(&device->alloc, pAllocator, buffer);
249 }
250
251 VkResult
252 val_CreateBufferView(VkDevice _device,
253 const VkBufferViewCreateInfo *pCreateInfo,
254 const VkAllocationCallbacks *pAllocator,
255 VkBufferView *pView)
256 {
257 VAL_FROM_HANDLE(val_device, device, _device);
258 VAL_FROM_HANDLE(val_buffer, buffer, pCreateInfo->buffer);
259 struct val_buffer_view *view;
260 view = vk_alloc2(&device->alloc, pAllocator, sizeof(*view), 8,
261 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
262 if (!view)
263 return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
264
265 vk_object_base_init(&device->vk, &view->base,
266 VK_OBJECT_TYPE_BUFFER_VIEW);
267 view->buffer = buffer;
268 view->format = pCreateInfo->format;
269 view->pformat = vk_format_to_pipe(pCreateInfo->format);
270 view->offset = pCreateInfo->offset;
271 view->range = pCreateInfo->range;
272 *pView = val_buffer_view_to_handle(view);
273
274 return VK_SUCCESS;
275 }
276
277 void
278 val_DestroyBufferView(VkDevice _device, VkBufferView bufferView,
279 const VkAllocationCallbacks *pAllocator)
280 {
281 VAL_FROM_HANDLE(val_device, device, _device);
282 VAL_FROM_HANDLE(val_buffer_view, view, bufferView);
283
284 if (!bufferView)
285 return;
286 vk_object_base_finish(&view->base);
287 vk_free2(&device->alloc, pAllocator, view);
288 }