Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/gallium/frontends/lavapipe/lvp_image.c
4565 views
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
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
break;
63
case VK_IMAGE_TYPE_3D:
64
template.target = PIPE_TEXTURE_3D;
65
break;
66
}
67
68
if (pCreateInfo->usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)
69
template.bind |= PIPE_BIND_RENDER_TARGET;
70
71
if (pCreateInfo->usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)
72
template.bind |= PIPE_BIND_DEPTH_STENCIL;
73
74
if (pCreateInfo->usage & VK_IMAGE_USAGE_SAMPLED_BIT)
75
template.bind |= PIPE_BIND_SAMPLER_VIEW;
76
77
if (pCreateInfo->usage & VK_IMAGE_USAGE_STORAGE_BIT)
78
template.bind |= PIPE_BIND_SHADER_IMAGE;
79
80
template.format = lvp_vk_format_to_pipe_format(pCreateInfo->format);
81
template.width0 = pCreateInfo->extent.width;
82
template.height0 = pCreateInfo->extent.height;
83
template.depth0 = pCreateInfo->extent.depth;
84
template.array_size = pCreateInfo->arrayLayers;
85
template.last_level = pCreateInfo->mipLevels - 1;
86
template.nr_samples = pCreateInfo->samples;
87
template.nr_storage_samples = pCreateInfo->samples;
88
if (create_info->bind_flags)
89
template.bind = create_info->bind_flags;
90
image->bo = device->pscreen->resource_create_unbacked(device->pscreen,
91
&template,
92
&image->size);
93
if (!image->bo)
94
return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
95
}
96
*pImage = lvp_image_to_handle(image);
97
98
return VK_SUCCESS;
99
}
100
101
struct lvp_image *
102
lvp_swapchain_get_image(VkSwapchainKHR swapchain,
103
uint32_t index)
104
{
105
uint32_t n_images = index + 1;
106
VkImage *images = malloc(sizeof(*images) * n_images);
107
VkResult result = wsi_common_get_images(swapchain, &n_images, images);
108
109
if (result != VK_SUCCESS && result != VK_INCOMPLETE) {
110
free(images);
111
return NULL;
112
}
113
114
LVP_FROM_HANDLE(lvp_image, image, images[index]);
115
free(images);
116
117
return image;
118
}
119
120
static VkResult
121
lvp_image_from_swapchain(VkDevice device,
122
const VkImageCreateInfo *pCreateInfo,
123
const VkImageSwapchainCreateInfoKHR *swapchain_info,
124
const VkAllocationCallbacks *pAllocator,
125
VkImage *pImage)
126
{
127
ASSERTED struct lvp_image *swapchain_image = lvp_swapchain_get_image(swapchain_info->swapchain, 0);
128
assert(swapchain_image);
129
130
assert(swapchain_image->type == pCreateInfo->imageType);
131
132
VkImageCreateInfo local_create_info;
133
local_create_info = *pCreateInfo;
134
local_create_info.pNext = NULL;
135
/* The following parameters are implictly selected by the wsi code. */
136
local_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
137
local_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
138
local_create_info.usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
139
140
assert(!(local_create_info.usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT));
141
return lvp_image_create(device,
142
&(struct lvp_image_create_info) {
143
.vk_info = &local_create_info,
144
},
145
pAllocator,
146
pImage);
147
}
148
149
VKAPI_ATTR VkResult VKAPI_CALL
150
lvp_CreateImage(VkDevice device,
151
const VkImageCreateInfo *pCreateInfo,
152
const VkAllocationCallbacks *pAllocator,
153
VkImage *pImage)
154
{
155
const VkImageSwapchainCreateInfoKHR *swapchain_info =
156
vk_find_struct_const(pCreateInfo->pNext, IMAGE_SWAPCHAIN_CREATE_INFO_KHR);
157
if (swapchain_info && swapchain_info->swapchain != VK_NULL_HANDLE)
158
return lvp_image_from_swapchain(device, pCreateInfo, swapchain_info,
159
pAllocator, pImage);
160
return lvp_image_create(device,
161
&(struct lvp_image_create_info) {
162
.vk_info = pCreateInfo,
163
.bind_flags = 0,
164
},
165
pAllocator,
166
pImage);
167
}
168
169
VKAPI_ATTR void VKAPI_CALL
170
lvp_DestroyImage(VkDevice _device, VkImage _image,
171
const VkAllocationCallbacks *pAllocator)
172
{
173
LVP_FROM_HANDLE(lvp_device, device, _device);
174
LVP_FROM_HANDLE(lvp_image, image, _image);
175
176
if (!_image)
177
return;
178
pipe_resource_reference(&image->bo, NULL);
179
vk_object_base_finish(&image->base);
180
vk_free2(&device->vk.alloc, pAllocator, image);
181
}
182
183
VKAPI_ATTR VkResult VKAPI_CALL
184
lvp_CreateImageView(VkDevice _device,
185
const VkImageViewCreateInfo *pCreateInfo,
186
const VkAllocationCallbacks *pAllocator,
187
VkImageView *pView)
188
{
189
LVP_FROM_HANDLE(lvp_device, device, _device);
190
LVP_FROM_HANDLE(lvp_image, image, pCreateInfo->image);
191
struct lvp_image_view *view;
192
193
view = vk_alloc2(&device->vk.alloc, pAllocator, sizeof(*view), 8,
194
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
195
if (view == NULL)
196
return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
197
198
vk_object_base_init(&device->vk, &view->base,
199
VK_OBJECT_TYPE_IMAGE_VIEW);
200
view->view_type = pCreateInfo->viewType;
201
view->format = pCreateInfo->format;
202
view->pformat = lvp_vk_format_to_pipe_format(pCreateInfo->format);
203
view->components = pCreateInfo->components;
204
view->subresourceRange = pCreateInfo->subresourceRange;
205
view->image = image;
206
view->surface = NULL;
207
*pView = lvp_image_view_to_handle(view);
208
209
return VK_SUCCESS;
210
}
211
212
VKAPI_ATTR void VKAPI_CALL
213
lvp_DestroyImageView(VkDevice _device, VkImageView _iview,
214
const VkAllocationCallbacks *pAllocator)
215
{
216
LVP_FROM_HANDLE(lvp_device, device, _device);
217
LVP_FROM_HANDLE(lvp_image_view, iview, _iview);
218
219
if (!_iview)
220
return;
221
222
pipe_surface_reference(&iview->surface, NULL);
223
vk_object_base_finish(&iview->base);
224
vk_free2(&device->vk.alloc, pAllocator, iview);
225
}
226
227
VKAPI_ATTR void VKAPI_CALL lvp_GetImageSubresourceLayout(
228
VkDevice _device,
229
VkImage _image,
230
const VkImageSubresource* pSubresource,
231
VkSubresourceLayout* pLayout)
232
{
233
LVP_FROM_HANDLE(lvp_device, device, _device);
234
LVP_FROM_HANDLE(lvp_image, image, _image);
235
uint64_t value;
236
237
device->pscreen->resource_get_param(device->pscreen,
238
NULL,
239
image->bo,
240
0,
241
pSubresource->arrayLayer,
242
pSubresource->mipLevel,
243
PIPE_RESOURCE_PARAM_STRIDE,
244
0, &value);
245
246
pLayout->rowPitch = value;
247
248
device->pscreen->resource_get_param(device->pscreen,
249
NULL,
250
image->bo,
251
0,
252
pSubresource->arrayLayer,
253
pSubresource->mipLevel,
254
PIPE_RESOURCE_PARAM_OFFSET,
255
0, &value);
256
257
pLayout->offset = value;
258
259
device->pscreen->resource_get_param(device->pscreen,
260
NULL,
261
image->bo,
262
0,
263
pSubresource->arrayLayer,
264
pSubresource->mipLevel,
265
PIPE_RESOURCE_PARAM_LAYER_STRIDE,
266
0, &value);
267
268
if (image->bo->target == PIPE_TEXTURE_3D) {
269
pLayout->depthPitch = value;
270
pLayout->arrayPitch = 0;
271
} else {
272
pLayout->depthPitch = 0;
273
pLayout->arrayPitch = value;
274
}
275
pLayout->size = image->size;
276
277
switch (pSubresource->aspectMask) {
278
case VK_IMAGE_ASPECT_COLOR_BIT:
279
break;
280
case VK_IMAGE_ASPECT_DEPTH_BIT:
281
break;
282
case VK_IMAGE_ASPECT_STENCIL_BIT:
283
break;
284
default:
285
assert(!"Invalid image aspect");
286
}
287
}
288
289
VKAPI_ATTR VkResult VKAPI_CALL lvp_CreateBuffer(
290
VkDevice _device,
291
const VkBufferCreateInfo* pCreateInfo,
292
const VkAllocationCallbacks* pAllocator,
293
VkBuffer* pBuffer)
294
{
295
LVP_FROM_HANDLE(lvp_device, device, _device);
296
struct lvp_buffer *buffer;
297
298
assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO);
299
300
/* gallium has max 32-bit buffer sizes */
301
if (pCreateInfo->size > UINT32_MAX)
302
return VK_ERROR_OUT_OF_DEVICE_MEMORY;
303
304
buffer = vk_alloc2(&device->vk.alloc, pAllocator, sizeof(*buffer), 8,
305
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
306
if (buffer == NULL)
307
return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
308
309
vk_object_base_init(&device->vk, &buffer->base, VK_OBJECT_TYPE_BUFFER);
310
buffer->size = pCreateInfo->size;
311
buffer->usage = pCreateInfo->usage;
312
buffer->offset = 0;
313
314
{
315
struct pipe_resource template;
316
memset(&template, 0, sizeof(struct pipe_resource));
317
318
if (pCreateInfo->usage & VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT)
319
template.bind |= PIPE_BIND_CONSTANT_BUFFER;
320
321
template.screen = device->pscreen;
322
template.target = PIPE_BUFFER;
323
template.format = PIPE_FORMAT_R8_UNORM;
324
template.width0 = buffer->size;
325
template.height0 = 1;
326
template.depth0 = 1;
327
template.array_size = 1;
328
if (buffer->usage & VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT)
329
template.bind |= PIPE_BIND_SAMPLER_VIEW;
330
if (buffer->usage & VK_BUFFER_USAGE_STORAGE_BUFFER_BIT)
331
template.bind |= PIPE_BIND_SHADER_BUFFER;
332
if (buffer->usage & VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT)
333
template.bind |= PIPE_BIND_SHADER_IMAGE;
334
template.flags = PIPE_RESOURCE_FLAG_DONT_OVER_ALLOCATE;
335
buffer->bo = device->pscreen->resource_create_unbacked(device->pscreen,
336
&template,
337
&buffer->total_size);
338
if (!buffer->bo) {
339
vk_free2(&device->vk.alloc, pAllocator, buffer);
340
return vk_error(device->instance, VK_ERROR_OUT_OF_DEVICE_MEMORY);
341
}
342
}
343
*pBuffer = lvp_buffer_to_handle(buffer);
344
345
return VK_SUCCESS;
346
}
347
348
VKAPI_ATTR void VKAPI_CALL lvp_DestroyBuffer(
349
VkDevice _device,
350
VkBuffer _buffer,
351
const VkAllocationCallbacks* pAllocator)
352
{
353
LVP_FROM_HANDLE(lvp_device, device, _device);
354
LVP_FROM_HANDLE(lvp_buffer, buffer, _buffer);
355
356
if (!_buffer)
357
return;
358
359
pipe_resource_reference(&buffer->bo, NULL);
360
vk_object_base_finish(&buffer->base);
361
vk_free2(&device->vk.alloc, pAllocator, buffer);
362
}
363
364
VKAPI_ATTR VkDeviceAddress VKAPI_CALL lvp_GetBufferDeviceAddress(
365
VkDevice device,
366
const VkBufferDeviceAddressInfoKHR* pInfo)
367
{
368
LVP_FROM_HANDLE(lvp_buffer, buffer, pInfo->buffer);
369
370
return (VkDeviceAddress)(uintptr_t)buffer->pmem;
371
}
372
373
VKAPI_ATTR uint64_t VKAPI_CALL lvp_GetBufferOpaqueCaptureAddress(
374
VkDevice device,
375
const VkBufferDeviceAddressInfoKHR* pInfo)
376
{
377
return 0;
378
}
379
380
VKAPI_ATTR uint64_t VKAPI_CALL lvp_GetDeviceMemoryOpaqueCaptureAddress(
381
VkDevice device,
382
const VkDeviceMemoryOpaqueCaptureAddressInfoKHR* pInfo)
383
{
384
return 0;
385
}
386
387
VKAPI_ATTR VkResult VKAPI_CALL
388
lvp_CreateBufferView(VkDevice _device,
389
const VkBufferViewCreateInfo *pCreateInfo,
390
const VkAllocationCallbacks *pAllocator,
391
VkBufferView *pView)
392
{
393
LVP_FROM_HANDLE(lvp_device, device, _device);
394
LVP_FROM_HANDLE(lvp_buffer, buffer, pCreateInfo->buffer);
395
struct lvp_buffer_view *view;
396
view = vk_alloc2(&device->vk.alloc, pAllocator, sizeof(*view), 8,
397
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
398
if (!view)
399
return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
400
401
vk_object_base_init(&device->vk, &view->base,
402
VK_OBJECT_TYPE_BUFFER_VIEW);
403
view->buffer = buffer;
404
view->format = pCreateInfo->format;
405
view->pformat = lvp_vk_format_to_pipe_format(pCreateInfo->format);
406
view->offset = pCreateInfo->offset;
407
view->range = pCreateInfo->range;
408
*pView = lvp_buffer_view_to_handle(view);
409
410
return VK_SUCCESS;
411
}
412
413
VKAPI_ATTR void VKAPI_CALL
414
lvp_DestroyBufferView(VkDevice _device, VkBufferView bufferView,
415
const VkAllocationCallbacks *pAllocator)
416
{
417
LVP_FROM_HANDLE(lvp_device, device, _device);
418
LVP_FROM_HANDLE(lvp_buffer_view, view, bufferView);
419
420
if (!bufferView)
421
return;
422
vk_object_base_finish(&view->base);
423
vk_free2(&device->vk.alloc, pAllocator, view);
424
}
425
426