Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/virtio/vulkan/vn_image.c
4560 views
1
/*
2
* Copyright 2019 Google LLC
3
* SPDX-License-Identifier: MIT
4
*
5
* based in part on anv and radv which are:
6
* Copyright © 2015 Intel Corporation
7
* Copyright © 2016 Red Hat.
8
* Copyright © 2016 Bas Nieuwenhuizen
9
*/
10
11
#include "vn_image.h"
12
13
#include "venus-protocol/vn_protocol_driver_image.h"
14
#include "venus-protocol/vn_protocol_driver_image_view.h"
15
#include "venus-protocol/vn_protocol_driver_sampler.h"
16
#include "venus-protocol/vn_protocol_driver_sampler_ycbcr_conversion.h"
17
18
#include "vn_android.h"
19
#include "vn_device.h"
20
#include "vn_device_memory.h"
21
22
static void
23
vn_image_init_memory_requirements(struct vn_image *img,
24
struct vn_device *dev,
25
const VkImageCreateInfo *create_info)
26
{
27
uint32_t plane_count = 1;
28
if (create_info->flags & VK_IMAGE_CREATE_DISJOINT_BIT) {
29
/* TODO VkDrmFormatModifierPropertiesEXT::drmFormatModifierPlaneCount */
30
assert(create_info->tiling != VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT);
31
32
switch (create_info->format) {
33
case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
34
case VK_FORMAT_G8_B8R8_2PLANE_422_UNORM:
35
case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16:
36
case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16:
37
case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16:
38
case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16:
39
case VK_FORMAT_G16_B16R16_2PLANE_420_UNORM:
40
case VK_FORMAT_G16_B16R16_2PLANE_422_UNORM:
41
plane_count = 2;
42
break;
43
case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM:
44
case VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM:
45
case VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM:
46
case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16:
47
case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16:
48
case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16:
49
case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16:
50
case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16:
51
case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16:
52
case VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM:
53
case VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM:
54
case VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM:
55
plane_count = 3;
56
break;
57
default:
58
plane_count = 1;
59
break;
60
}
61
}
62
assert(plane_count <= ARRAY_SIZE(img->memory_requirements));
63
64
/* TODO add a per-device cache for the requirements */
65
for (uint32_t i = 0; i < plane_count; i++) {
66
img->memory_requirements[i].sType =
67
VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2;
68
img->memory_requirements[i].pNext = &img->dedicated_requirements[i];
69
img->dedicated_requirements[i].sType =
70
VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS;
71
img->dedicated_requirements[i].pNext = NULL;
72
}
73
74
VkDevice dev_handle = vn_device_to_handle(dev);
75
VkImage img_handle = vn_image_to_handle(img);
76
if (plane_count == 1) {
77
vn_call_vkGetImageMemoryRequirements2(
78
dev->instance, dev_handle,
79
&(VkImageMemoryRequirementsInfo2){
80
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2,
81
.image = img_handle,
82
},
83
&img->memory_requirements[0]);
84
85
/* AHB backed image requires dedicated allocation */
86
if (img->deferred_info) {
87
img->dedicated_requirements[0].prefersDedicatedAllocation = VK_TRUE;
88
img->dedicated_requirements[0].requiresDedicatedAllocation = VK_TRUE;
89
}
90
} else {
91
for (uint32_t i = 0; i < plane_count; i++) {
92
vn_call_vkGetImageMemoryRequirements2(
93
dev->instance, dev_handle,
94
&(VkImageMemoryRequirementsInfo2){
95
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2,
96
.pNext =
97
&(VkImagePlaneMemoryRequirementsInfo){
98
.sType =
99
VK_STRUCTURE_TYPE_IMAGE_PLANE_MEMORY_REQUIREMENTS_INFO,
100
.planeAspect = VK_IMAGE_ASPECT_PLANE_0_BIT << i,
101
},
102
.image = img_handle,
103
},
104
&img->memory_requirements[i]);
105
}
106
}
107
}
108
109
static VkResult
110
vn_image_store_deferred_create_info(
111
const VkImageCreateInfo *create_info,
112
const VkAllocationCallbacks *alloc,
113
struct vn_image_create_deferred_info **out_info)
114
{
115
struct vn_image_create_deferred_info *info = NULL;
116
VkBaseOutStructure *dst = NULL;
117
118
info = vk_zalloc(alloc, sizeof(*info), VN_DEFAULT_ALIGN,
119
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
120
if (!info)
121
return VK_ERROR_OUT_OF_HOST_MEMORY;
122
123
info->create = *create_info;
124
dst = (void *)&info->create;
125
126
vk_foreach_struct_const(src, create_info->pNext) {
127
void *pnext = NULL;
128
switch (src->sType) {
129
case VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO:
130
memcpy(&info->list, src, sizeof(info->list));
131
pnext = &info->list;
132
break;
133
case VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO:
134
memcpy(&info->stencil, src, sizeof(info->stencil));
135
pnext = &info->stencil;
136
break;
137
default:
138
break;
139
}
140
141
if (pnext) {
142
dst->pNext = pnext;
143
dst = pnext;
144
}
145
}
146
dst->pNext = NULL;
147
148
*out_info = info;
149
150
return VK_SUCCESS;
151
}
152
153
static VkResult
154
vn_image_init(struct vn_device *dev,
155
const VkImageCreateInfo *create_info,
156
struct vn_image *img)
157
{
158
VkDevice device = vn_device_to_handle(dev);
159
VkImage image = vn_image_to_handle(img);
160
VkResult result = VK_SUCCESS;
161
162
img->sharing_mode = create_info->sharingMode;
163
164
/* TODO async */
165
result =
166
vn_call_vkCreateImage(dev->instance, device, create_info, NULL, &image);
167
if (result != VK_SUCCESS)
168
return result;
169
170
vn_image_init_memory_requirements(img, dev, create_info);
171
172
return VK_SUCCESS;
173
}
174
175
VkResult
176
vn_image_create(struct vn_device *dev,
177
const VkImageCreateInfo *create_info,
178
const VkAllocationCallbacks *alloc,
179
struct vn_image **out_img)
180
{
181
struct vn_image *img = NULL;
182
VkResult result = VK_SUCCESS;
183
184
img = vk_zalloc(alloc, sizeof(*img), VN_DEFAULT_ALIGN,
185
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
186
if (!img)
187
return VK_ERROR_OUT_OF_HOST_MEMORY;
188
189
vn_object_base_init(&img->base, VK_OBJECT_TYPE_IMAGE, &dev->base);
190
191
result = vn_image_init(dev, create_info, img);
192
if (result != VK_SUCCESS) {
193
vk_free(alloc, img);
194
return result;
195
}
196
197
*out_img = img;
198
199
return VK_SUCCESS;
200
}
201
202
VkResult
203
vn_image_init_deferred(struct vn_device *dev,
204
const VkImageCreateInfo *create_info,
205
struct vn_image *img)
206
{
207
return vn_image_init(dev, create_info, img);
208
}
209
210
VkResult
211
vn_image_create_deferred(struct vn_device *dev,
212
const VkImageCreateInfo *create_info,
213
const VkAllocationCallbacks *alloc,
214
struct vn_image **out_img)
215
{
216
struct vn_image *img = NULL;
217
VkResult result = VK_SUCCESS;
218
219
img = vk_zalloc(alloc, sizeof(*img), VN_DEFAULT_ALIGN,
220
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
221
if (!img)
222
return VK_ERROR_OUT_OF_HOST_MEMORY;
223
224
vn_object_base_init(&img->base, VK_OBJECT_TYPE_IMAGE, &dev->base);
225
226
result = vn_image_store_deferred_create_info(create_info, alloc,
227
&img->deferred_info);
228
if (result != VK_SUCCESS) {
229
vk_free(alloc, img);
230
return result;
231
}
232
233
*out_img = img;
234
235
return VK_SUCCESS;
236
}
237
238
/* image commands */
239
240
VkResult
241
vn_CreateImage(VkDevice device,
242
const VkImageCreateInfo *pCreateInfo,
243
const VkAllocationCallbacks *pAllocator,
244
VkImage *pImage)
245
{
246
struct vn_device *dev = vn_device_from_handle(device);
247
const VkAllocationCallbacks *alloc =
248
pAllocator ? pAllocator : &dev->base.base.alloc;
249
struct vn_image *img;
250
VkResult result;
251
252
const struct wsi_image_create_info *wsi_info =
253
vn_wsi_find_wsi_image_create_info(pCreateInfo);
254
const VkNativeBufferANDROID *anb_info =
255
vn_android_find_native_buffer(pCreateInfo);
256
const VkExternalMemoryImageCreateInfo *external_info =
257
vk_find_struct_const(pCreateInfo->pNext,
258
EXTERNAL_MEMORY_IMAGE_CREATE_INFO);
259
const bool ahb_info =
260
external_info &&
261
external_info->handleTypes ==
262
VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID;
263
264
if (wsi_info) {
265
result = vn_wsi_create_image(dev, pCreateInfo, wsi_info, alloc, &img);
266
} else if (anb_info) {
267
result =
268
vn_android_image_from_anb(dev, pCreateInfo, anb_info, alloc, &img);
269
} else if (ahb_info) {
270
result = vn_android_image_from_ahb(dev, pCreateInfo, alloc, &img);
271
} else {
272
result = vn_image_create(dev, pCreateInfo, alloc, &img);
273
}
274
275
if (result != VK_SUCCESS)
276
return vn_error(dev->instance, result);
277
278
*pImage = vn_image_to_handle(img);
279
return VK_SUCCESS;
280
}
281
282
void
283
vn_DestroyImage(VkDevice device,
284
VkImage image,
285
const VkAllocationCallbacks *pAllocator)
286
{
287
struct vn_device *dev = vn_device_from_handle(device);
288
struct vn_image *img = vn_image_from_handle(image);
289
const VkAllocationCallbacks *alloc =
290
pAllocator ? pAllocator : &dev->base.base.alloc;
291
292
if (!img)
293
return;
294
295
if (img->private_memory != VK_NULL_HANDLE)
296
vn_FreeMemory(device, img->private_memory, pAllocator);
297
298
vn_async_vkDestroyImage(dev->instance, device, image, NULL);
299
300
if (img->deferred_info)
301
vk_free(alloc, img->deferred_info);
302
303
vn_object_base_fini(&img->base);
304
vk_free(alloc, img);
305
}
306
307
void
308
vn_GetImageMemoryRequirements(VkDevice device,
309
VkImage image,
310
VkMemoryRequirements *pMemoryRequirements)
311
{
312
const struct vn_image *img = vn_image_from_handle(image);
313
314
*pMemoryRequirements = img->memory_requirements[0].memoryRequirements;
315
}
316
317
void
318
vn_GetImageSparseMemoryRequirements(
319
VkDevice device,
320
VkImage image,
321
uint32_t *pSparseMemoryRequirementCount,
322
VkSparseImageMemoryRequirements *pSparseMemoryRequirements)
323
{
324
struct vn_device *dev = vn_device_from_handle(device);
325
326
/* TODO per-device cache */
327
vn_call_vkGetImageSparseMemoryRequirements(dev->instance, device, image,
328
pSparseMemoryRequirementCount,
329
pSparseMemoryRequirements);
330
}
331
332
void
333
vn_GetImageMemoryRequirements2(VkDevice device,
334
const VkImageMemoryRequirementsInfo2 *pInfo,
335
VkMemoryRequirements2 *pMemoryRequirements)
336
{
337
const struct vn_image *img = vn_image_from_handle(pInfo->image);
338
union {
339
VkBaseOutStructure *pnext;
340
VkMemoryRequirements2 *two;
341
VkMemoryDedicatedRequirements *dedicated;
342
} u = { .two = pMemoryRequirements };
343
344
uint32_t plane = 0;
345
const VkImagePlaneMemoryRequirementsInfo *plane_info =
346
vk_find_struct_const(pInfo->pNext,
347
IMAGE_PLANE_MEMORY_REQUIREMENTS_INFO);
348
if (plane_info) {
349
switch (plane_info->planeAspect) {
350
case VK_IMAGE_ASPECT_PLANE_1_BIT:
351
plane = 1;
352
break;
353
case VK_IMAGE_ASPECT_PLANE_2_BIT:
354
plane = 2;
355
break;
356
default:
357
plane = 0;
358
break;
359
}
360
}
361
362
while (u.pnext) {
363
switch (u.pnext->sType) {
364
case VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2:
365
u.two->memoryRequirements =
366
img->memory_requirements[plane].memoryRequirements;
367
break;
368
case VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS:
369
u.dedicated->prefersDedicatedAllocation =
370
img->dedicated_requirements[plane].prefersDedicatedAllocation;
371
u.dedicated->requiresDedicatedAllocation =
372
img->dedicated_requirements[plane].requiresDedicatedAllocation;
373
break;
374
default:
375
break;
376
}
377
u.pnext = u.pnext->pNext;
378
}
379
}
380
381
void
382
vn_GetImageSparseMemoryRequirements2(
383
VkDevice device,
384
const VkImageSparseMemoryRequirementsInfo2 *pInfo,
385
uint32_t *pSparseMemoryRequirementCount,
386
VkSparseImageMemoryRequirements2 *pSparseMemoryRequirements)
387
{
388
struct vn_device *dev = vn_device_from_handle(device);
389
390
/* TODO per-device cache */
391
vn_call_vkGetImageSparseMemoryRequirements2(dev->instance, device, pInfo,
392
pSparseMemoryRequirementCount,
393
pSparseMemoryRequirements);
394
}
395
396
VkResult
397
vn_BindImageMemory(VkDevice device,
398
VkImage image,
399
VkDeviceMemory memory,
400
VkDeviceSize memoryOffset)
401
{
402
struct vn_device *dev = vn_device_from_handle(device);
403
struct vn_device_memory *mem = vn_device_memory_from_handle(memory);
404
405
if (mem->base_memory) {
406
memory = vn_device_memory_to_handle(mem->base_memory);
407
memoryOffset += mem->base_offset;
408
}
409
410
vn_async_vkBindImageMemory(dev->instance, device, image, memory,
411
memoryOffset);
412
413
return VK_SUCCESS;
414
}
415
416
VkResult
417
vn_BindImageMemory2(VkDevice device,
418
uint32_t bindInfoCount,
419
const VkBindImageMemoryInfo *pBindInfos)
420
{
421
struct vn_device *dev = vn_device_from_handle(device);
422
const VkAllocationCallbacks *alloc = &dev->base.base.alloc;
423
424
VkBindImageMemoryInfo *local_infos = NULL;
425
for (uint32_t i = 0; i < bindInfoCount; i++) {
426
const VkBindImageMemoryInfo *info = &pBindInfos[i];
427
struct vn_device_memory *mem =
428
vn_device_memory_from_handle(info->memory);
429
/* TODO handle VkBindImageMemorySwapchainInfoKHR */
430
if (!mem || !mem->base_memory)
431
continue;
432
433
if (!local_infos) {
434
const size_t size = sizeof(*local_infos) * bindInfoCount;
435
local_infos = vk_alloc(alloc, size, VN_DEFAULT_ALIGN,
436
VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
437
if (!local_infos)
438
return vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
439
440
memcpy(local_infos, pBindInfos, size);
441
}
442
443
local_infos[i].memory = vn_device_memory_to_handle(mem->base_memory);
444
local_infos[i].memoryOffset += mem->base_offset;
445
}
446
if (local_infos)
447
pBindInfos = local_infos;
448
449
vn_async_vkBindImageMemory2(dev->instance, device, bindInfoCount,
450
pBindInfos);
451
452
vk_free(alloc, local_infos);
453
454
return VK_SUCCESS;
455
}
456
457
VkResult
458
vn_GetImageDrmFormatModifierPropertiesEXT(
459
VkDevice device,
460
VkImage image,
461
VkImageDrmFormatModifierPropertiesEXT *pProperties)
462
{
463
struct vn_device *dev = vn_device_from_handle(device);
464
465
/* TODO local cache */
466
return vn_call_vkGetImageDrmFormatModifierPropertiesEXT(
467
dev->instance, device, image, pProperties);
468
}
469
470
void
471
vn_GetImageSubresourceLayout(VkDevice device,
472
VkImage image,
473
const VkImageSubresource *pSubresource,
474
VkSubresourceLayout *pLayout)
475
{
476
struct vn_device *dev = vn_device_from_handle(device);
477
478
/* TODO local cache */
479
vn_call_vkGetImageSubresourceLayout(dev->instance, device, image,
480
pSubresource, pLayout);
481
}
482
483
/* image view commands */
484
485
VkResult
486
vn_CreateImageView(VkDevice device,
487
const VkImageViewCreateInfo *pCreateInfo,
488
const VkAllocationCallbacks *pAllocator,
489
VkImageView *pView)
490
{
491
struct vn_device *dev = vn_device_from_handle(device);
492
const VkAllocationCallbacks *alloc =
493
pAllocator ? pAllocator : &dev->base.base.alloc;
494
495
struct vn_image_view *view =
496
vk_zalloc(alloc, sizeof(*view), VN_DEFAULT_ALIGN,
497
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
498
if (!view)
499
return vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
500
501
vn_object_base_init(&view->base, VK_OBJECT_TYPE_IMAGE_VIEW, &dev->base);
502
view->image = vn_image_from_handle(pCreateInfo->image);
503
504
VkImageView view_handle = vn_image_view_to_handle(view);
505
vn_async_vkCreateImageView(dev->instance, device, pCreateInfo, NULL,
506
&view_handle);
507
508
*pView = view_handle;
509
510
return VK_SUCCESS;
511
}
512
513
void
514
vn_DestroyImageView(VkDevice device,
515
VkImageView imageView,
516
const VkAllocationCallbacks *pAllocator)
517
{
518
struct vn_device *dev = vn_device_from_handle(device);
519
struct vn_image_view *view = vn_image_view_from_handle(imageView);
520
const VkAllocationCallbacks *alloc =
521
pAllocator ? pAllocator : &dev->base.base.alloc;
522
523
if (!view)
524
return;
525
526
vn_async_vkDestroyImageView(dev->instance, device, imageView, NULL);
527
528
vn_object_base_fini(&view->base);
529
vk_free(alloc, view);
530
}
531
532
/* sampler commands */
533
534
VkResult
535
vn_CreateSampler(VkDevice device,
536
const VkSamplerCreateInfo *pCreateInfo,
537
const VkAllocationCallbacks *pAllocator,
538
VkSampler *pSampler)
539
{
540
struct vn_device *dev = vn_device_from_handle(device);
541
const VkAllocationCallbacks *alloc =
542
pAllocator ? pAllocator : &dev->base.base.alloc;
543
544
struct vn_sampler *sampler =
545
vk_zalloc(alloc, sizeof(*sampler), VN_DEFAULT_ALIGN,
546
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
547
if (!sampler)
548
return vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
549
550
vn_object_base_init(&sampler->base, VK_OBJECT_TYPE_SAMPLER, &dev->base);
551
552
VkSampler sampler_handle = vn_sampler_to_handle(sampler);
553
vn_async_vkCreateSampler(dev->instance, device, pCreateInfo, NULL,
554
&sampler_handle);
555
556
*pSampler = sampler_handle;
557
558
return VK_SUCCESS;
559
}
560
561
void
562
vn_DestroySampler(VkDevice device,
563
VkSampler _sampler,
564
const VkAllocationCallbacks *pAllocator)
565
{
566
struct vn_device *dev = vn_device_from_handle(device);
567
struct vn_sampler *sampler = vn_sampler_from_handle(_sampler);
568
const VkAllocationCallbacks *alloc =
569
pAllocator ? pAllocator : &dev->base.base.alloc;
570
571
if (!sampler)
572
return;
573
574
vn_async_vkDestroySampler(dev->instance, device, _sampler, NULL);
575
576
vn_object_base_fini(&sampler->base);
577
vk_free(alloc, sampler);
578
}
579
580
/* sampler YCbCr conversion commands */
581
582
VkResult
583
vn_CreateSamplerYcbcrConversion(
584
VkDevice device,
585
const VkSamplerYcbcrConversionCreateInfo *pCreateInfo,
586
const VkAllocationCallbacks *pAllocator,
587
VkSamplerYcbcrConversion *pYcbcrConversion)
588
{
589
struct vn_device *dev = vn_device_from_handle(device);
590
const VkAllocationCallbacks *alloc =
591
pAllocator ? pAllocator : &dev->base.base.alloc;
592
const VkExternalFormatANDROID *ext_info =
593
vk_find_struct_const(pCreateInfo->pNext, EXTERNAL_FORMAT_ANDROID);
594
595
VkSamplerYcbcrConversionCreateInfo local_info;
596
if (ext_info && ext_info->externalFormat) {
597
assert(pCreateInfo->format == VK_FORMAT_UNDEFINED);
598
599
local_info = *pCreateInfo;
600
local_info.format =
601
vn_android_drm_format_to_vk_format(ext_info->externalFormat);
602
local_info.components.r = VK_COMPONENT_SWIZZLE_IDENTITY;
603
local_info.components.g = VK_COMPONENT_SWIZZLE_IDENTITY;
604
local_info.components.b = VK_COMPONENT_SWIZZLE_IDENTITY;
605
local_info.components.a = VK_COMPONENT_SWIZZLE_IDENTITY;
606
pCreateInfo = &local_info;
607
608
assert(pCreateInfo->format != VK_FORMAT_UNDEFINED);
609
}
610
611
struct vn_sampler_ycbcr_conversion *conv =
612
vk_zalloc(alloc, sizeof(*conv), VN_DEFAULT_ALIGN,
613
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
614
if (!conv)
615
return vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
616
617
vn_object_base_init(&conv->base, VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION,
618
&dev->base);
619
620
VkSamplerYcbcrConversion conv_handle =
621
vn_sampler_ycbcr_conversion_to_handle(conv);
622
vn_async_vkCreateSamplerYcbcrConversion(dev->instance, device, pCreateInfo,
623
NULL, &conv_handle);
624
625
*pYcbcrConversion = conv_handle;
626
627
return VK_SUCCESS;
628
}
629
630
void
631
vn_DestroySamplerYcbcrConversion(VkDevice device,
632
VkSamplerYcbcrConversion ycbcrConversion,
633
const VkAllocationCallbacks *pAllocator)
634
{
635
struct vn_device *dev = vn_device_from_handle(device);
636
struct vn_sampler_ycbcr_conversion *conv =
637
vn_sampler_ycbcr_conversion_from_handle(ycbcrConversion);
638
const VkAllocationCallbacks *alloc =
639
pAllocator ? pAllocator : &dev->base.base.alloc;
640
641
if (!conv)
642
return;
643
644
vn_async_vkDestroySamplerYcbcrConversion(dev->instance, device,
645
ycbcrConversion, NULL);
646
647
vn_object_base_fini(&conv->base);
648
vk_free(alloc, conv);
649
}
650
651