Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/vulkan/wsi/wsi_common_win32.c
7326 views
1
/*
2
* Copyright © 2015 Intel Corporation
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 <assert.h>
25
#include <stdlib.h>
26
#include <stdio.h>
27
#include <string.h>
28
29
#include "vk_util.h"
30
#include "wsi_common_private.h"
31
#include "wsi_common_win32.h"
32
33
#if defined(__GNUC__)
34
#pragma GCC diagnostic ignored "-Wint-to-pointer-cast" // warning: cast to pointer from integer of different size
35
#endif
36
37
struct wsi_win32;
38
39
struct wsi_win32 {
40
struct wsi_interface base;
41
42
struct wsi_device *wsi;
43
44
const VkAllocationCallbacks *alloc;
45
VkPhysicalDevice physical_device;
46
};
47
48
struct wsi_win32_image {
49
struct wsi_image base;
50
struct wsi_win32_swapchain *chain;
51
HDC dc;
52
HBITMAP bmp;
53
int bmp_row_pitch;
54
void *ppvBits;
55
};
56
57
58
struct wsi_win32_swapchain {
59
struct wsi_swapchain base;
60
struct wsi_win32 *wsi;
61
VkIcdSurfaceWin32 *surface;
62
uint64_t flip_sequence;
63
VkResult status;
64
VkExtent2D extent;
65
HWND wnd;
66
HDC chain_dc;
67
struct wsi_win32_image images[0];
68
};
69
70
VkBool32
71
wsi_win32_get_presentation_support(struct wsi_device *wsi_device)
72
{
73
return TRUE;
74
}
75
76
VkResult
77
wsi_create_win32_surface(VkInstance instance,
78
const VkAllocationCallbacks *allocator,
79
const VkWin32SurfaceCreateInfoKHR *create_info,
80
VkSurfaceKHR *surface_khr)
81
{
82
VkIcdSurfaceWin32 *surface = vk_zalloc(allocator, sizeof *surface, 8,
83
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
84
85
if (surface == NULL)
86
return VK_ERROR_OUT_OF_HOST_MEMORY;
87
88
surface->base.platform = VK_ICD_WSI_PLATFORM_WIN32;
89
90
surface->hinstance = create_info->hinstance;
91
surface->hwnd = create_info->hwnd;
92
93
*surface_khr = VkIcdSurfaceBase_to_handle(&surface->base);
94
return VK_SUCCESS;
95
}
96
97
static VkResult
98
wsi_win32_surface_get_support(VkIcdSurfaceBase *surface,
99
struct wsi_device *wsi_device,
100
uint32_t queueFamilyIndex,
101
VkBool32* pSupported)
102
{
103
*pSupported = true;
104
105
return VK_SUCCESS;
106
}
107
108
static VkResult
109
wsi_win32_surface_get_capabilities(VkIcdSurfaceBase *surface,
110
struct wsi_device *wsi_device,
111
VkSurfaceCapabilitiesKHR* caps)
112
{
113
caps->minImageCount = 1;
114
/* There is no real maximum */
115
caps->maxImageCount = 0;
116
117
caps->currentExtent = (VkExtent2D) { UINT32_MAX, UINT32_MAX };
118
caps->minImageExtent = (VkExtent2D) { 1, 1 };
119
caps->maxImageExtent = (VkExtent2D) {
120
wsi_device->maxImageDimension2D,
121
wsi_device->maxImageDimension2D,
122
};
123
124
caps->supportedTransforms = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
125
caps->currentTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
126
caps->maxImageArrayLayers = 1;
127
128
caps->supportedCompositeAlpha =
129
VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR |
130
VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR;
131
132
caps->supportedUsageFlags =
133
VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
134
VK_IMAGE_USAGE_SAMPLED_BIT |
135
VK_IMAGE_USAGE_TRANSFER_DST_BIT |
136
VK_IMAGE_USAGE_STORAGE_BIT |
137
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
138
139
return VK_SUCCESS;
140
}
141
142
static VkResult
143
wsi_win32_surface_get_capabilities2(VkIcdSurfaceBase *surface,
144
struct wsi_device *wsi_device,
145
const void *info_next,
146
VkSurfaceCapabilities2KHR* caps)
147
{
148
assert(caps->sType == VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_KHR);
149
150
VkResult result =
151
wsi_win32_surface_get_capabilities(surface, wsi_device,
152
&caps->surfaceCapabilities);
153
154
vk_foreach_struct(ext, caps->pNext) {
155
switch (ext->sType) {
156
case VK_STRUCTURE_TYPE_SURFACE_PROTECTED_CAPABILITIES_KHR: {
157
VkSurfaceProtectedCapabilitiesKHR *protected = (void *)ext;
158
protected->supportsProtected = VK_FALSE;
159
break;
160
}
161
162
default:
163
/* Ignored */
164
break;
165
}
166
}
167
168
return result;
169
}
170
171
172
static const struct {
173
VkFormat format;
174
} available_surface_formats[] = {
175
{ .format = VK_FORMAT_B8G8R8A8_SRGB },
176
{ .format = VK_FORMAT_B8G8R8A8_UNORM },
177
};
178
179
180
static void
181
get_sorted_vk_formats(struct wsi_device *wsi_device, VkFormat *sorted_formats)
182
{
183
for (unsigned i = 0; i < ARRAY_SIZE(available_surface_formats); i++)
184
sorted_formats[i] = available_surface_formats[i].format;
185
186
if (wsi_device->force_bgra8_unorm_first) {
187
for (unsigned i = 0; i < ARRAY_SIZE(available_surface_formats); i++) {
188
if (sorted_formats[i] == VK_FORMAT_B8G8R8A8_UNORM) {
189
sorted_formats[i] = sorted_formats[0];
190
sorted_formats[0] = VK_FORMAT_B8G8R8A8_UNORM;
191
break;
192
}
193
}
194
}
195
}
196
197
static VkResult
198
wsi_win32_surface_get_formats(VkIcdSurfaceBase *icd_surface,
199
struct wsi_device *wsi_device,
200
uint32_t* pSurfaceFormatCount,
201
VkSurfaceFormatKHR* pSurfaceFormats)
202
{
203
VK_OUTARRAY_MAKE_TYPED(VkSurfaceFormatKHR, out, pSurfaceFormats, pSurfaceFormatCount);
204
205
VkFormat sorted_formats[ARRAY_SIZE(available_surface_formats)];
206
get_sorted_vk_formats(wsi_device, sorted_formats);
207
208
for (unsigned i = 0; i < ARRAY_SIZE(sorted_formats); i++) {
209
vk_outarray_append_typed(VkSurfaceFormatKHR, &out, f) {
210
f->format = sorted_formats[i];
211
f->colorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR;
212
}
213
}
214
215
return vk_outarray_status(&out);
216
}
217
218
static VkResult
219
wsi_win32_surface_get_formats2(VkIcdSurfaceBase *icd_surface,
220
struct wsi_device *wsi_device,
221
const void *info_next,
222
uint32_t* pSurfaceFormatCount,
223
VkSurfaceFormat2KHR* pSurfaceFormats)
224
{
225
VK_OUTARRAY_MAKE_TYPED(VkSurfaceFormat2KHR, out, pSurfaceFormats, pSurfaceFormatCount);
226
227
VkFormat sorted_formats[ARRAY_SIZE(available_surface_formats)];
228
get_sorted_vk_formats(wsi_device, sorted_formats);
229
230
for (unsigned i = 0; i < ARRAY_SIZE(sorted_formats); i++) {
231
vk_outarray_append_typed(VkSurfaceFormat2KHR, &out, f) {
232
assert(f->sType == VK_STRUCTURE_TYPE_SURFACE_FORMAT_2_KHR);
233
f->surfaceFormat.format = sorted_formats[i];
234
f->surfaceFormat.colorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR;
235
}
236
}
237
238
return vk_outarray_status(&out);
239
}
240
241
static const VkPresentModeKHR present_modes[] = {
242
//VK_PRESENT_MODE_MAILBOX_KHR,
243
VK_PRESENT_MODE_FIFO_KHR,
244
};
245
246
static VkResult
247
wsi_win32_surface_get_present_modes(VkIcdSurfaceBase *surface,
248
uint32_t* pPresentModeCount,
249
VkPresentModeKHR* pPresentModes)
250
{
251
if (pPresentModes == NULL) {
252
*pPresentModeCount = ARRAY_SIZE(present_modes);
253
return VK_SUCCESS;
254
}
255
256
*pPresentModeCount = MIN2(*pPresentModeCount, ARRAY_SIZE(present_modes));
257
typed_memcpy(pPresentModes, present_modes, *pPresentModeCount);
258
259
if (*pPresentModeCount < ARRAY_SIZE(present_modes))
260
return VK_INCOMPLETE;
261
else
262
return VK_SUCCESS;
263
}
264
265
static VkResult
266
wsi_win32_surface_get_present_rectangles(VkIcdSurfaceBase *surface,
267
struct wsi_device *wsi_device,
268
uint32_t* pRectCount,
269
VkRect2D* pRects)
270
{
271
VK_OUTARRAY_MAKE_TYPED(VkRect2D, out, pRects, pRectCount);
272
273
vk_outarray_append_typed(VkRect2D, &out, rect) {
274
/* We don't know a size so just return the usual "I don't know." */
275
*rect = (VkRect2D) {
276
.offset = { 0, 0 },
277
.extent = { UINT32_MAX, UINT32_MAX },
278
};
279
}
280
281
return vk_outarray_status(&out);
282
}
283
284
static uint32_t
285
select_memory_type(const struct wsi_device *wsi,
286
VkMemoryPropertyFlags props,
287
uint32_t type_bits)
288
{
289
for (uint32_t i = 0; i < wsi->memory_props.memoryTypeCount; i++) {
290
const VkMemoryType type = wsi->memory_props.memoryTypes[i];
291
if ((type_bits & (1 << i)) && (type.propertyFlags & props) == props)
292
return i;
293
}
294
295
unreachable("No memory type found");
296
}
297
298
VkResult
299
wsi_create_native_image(const struct wsi_swapchain *chain,
300
const VkSwapchainCreateInfoKHR *pCreateInfo,
301
uint32_t num_modifier_lists,
302
const uint32_t *num_modifiers,
303
const uint64_t *const *modifiers,
304
struct wsi_image *image)
305
{
306
const struct wsi_device *wsi = chain->wsi;
307
VkResult result;
308
309
memset(image, 0, sizeof(*image));
310
for (int i = 0; i < ARRAY_SIZE(image->fds); i++)
311
image->fds[i] = -1;
312
313
const struct wsi_image_create_info image_wsi_info = {
314
.sType = VK_STRUCTURE_TYPE_WSI_IMAGE_CREATE_INFO_MESA,
315
};
316
VkImageCreateInfo image_info = {
317
.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
318
.pNext = &image_wsi_info,
319
.flags = 0,
320
.imageType = VK_IMAGE_TYPE_2D,
321
.format = pCreateInfo->imageFormat,
322
.extent = {
323
.width = pCreateInfo->imageExtent.width,
324
.height = pCreateInfo->imageExtent.height,
325
.depth = 1,
326
},
327
.mipLevels = 1,
328
.arrayLayers = 1,
329
.samples = VK_SAMPLE_COUNT_1_BIT,
330
.tiling = VK_IMAGE_TILING_OPTIMAL,
331
.usage = pCreateInfo->imageUsage,
332
.sharingMode = pCreateInfo->imageSharingMode,
333
.queueFamilyIndexCount = pCreateInfo->queueFamilyIndexCount,
334
.pQueueFamilyIndices = pCreateInfo->pQueueFamilyIndices,
335
.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
336
};
337
338
VkImageFormatListCreateInfoKHR image_format_list;
339
if (pCreateInfo->flags & VK_SWAPCHAIN_CREATE_MUTABLE_FORMAT_BIT_KHR) {
340
image_info.flags |= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT |
341
VK_IMAGE_CREATE_EXTENDED_USAGE_BIT_KHR;
342
343
const VkImageFormatListCreateInfoKHR *format_list =
344
vk_find_struct_const(pCreateInfo->pNext,
345
IMAGE_FORMAT_LIST_CREATE_INFO_KHR);
346
347
#ifndef NDEBUG
348
assume(format_list && format_list->viewFormatCount > 0);
349
bool format_found = false;
350
for (int i = 0; i < format_list->viewFormatCount; i++)
351
if (pCreateInfo->imageFormat == format_list->pViewFormats[i])
352
format_found = true;
353
assert(format_found);
354
#endif
355
356
image_format_list = *format_list;
357
image_format_list.pNext = NULL;
358
__vk_append_struct(&image_info, &image_format_list);
359
}
360
361
362
result = wsi->CreateImage(chain->device, &image_info,
363
&chain->alloc, &image->image);
364
if (result != VK_SUCCESS)
365
goto fail;
366
367
VkMemoryRequirements reqs;
368
wsi->GetImageMemoryRequirements(chain->device, image->image, &reqs);
369
370
const struct wsi_memory_allocate_info memory_wsi_info = {
371
.sType = VK_STRUCTURE_TYPE_WSI_MEMORY_ALLOCATE_INFO_MESA,
372
.pNext = NULL,
373
.implicit_sync = true,
374
};
375
const VkExportMemoryAllocateInfo memory_export_info = {
376
.sType = VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO,
377
.pNext = &memory_wsi_info,
378
.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,
379
};
380
const VkMemoryDedicatedAllocateInfo memory_dedicated_info = {
381
.sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO,
382
.pNext = &memory_export_info,
383
.image = image->image,
384
.buffer = VK_NULL_HANDLE,
385
};
386
const VkMemoryAllocateInfo memory_info = {
387
.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
388
.pNext = &memory_dedicated_info,
389
.allocationSize = reqs.size,
390
.memoryTypeIndex = select_memory_type(wsi, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
391
reqs.memoryTypeBits),
392
};
393
result = wsi->AllocateMemory(chain->device, &memory_info,
394
&chain->alloc, &image->memory);
395
if (result != VK_SUCCESS)
396
goto fail;
397
398
result = wsi->BindImageMemory(chain->device, image->image,
399
image->memory, 0);
400
if (result != VK_SUCCESS)
401
goto fail;
402
403
const VkImageSubresource image_subresource = {
404
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
405
.mipLevel = 0,
406
.arrayLayer = 0,
407
};
408
VkSubresourceLayout image_layout;
409
wsi->GetImageSubresourceLayout(chain->device, image->image,
410
&image_subresource, &image_layout);
411
412
image->num_planes = 1;
413
image->sizes[0] = reqs.size;
414
image->row_pitches[0] = image_layout.rowPitch;
415
image->offsets[0] = 0;
416
417
return VK_SUCCESS;
418
419
fail:
420
wsi_destroy_image(chain, image);
421
422
return result;
423
}
424
425
static VkResult
426
wsi_win32_image_init(VkDevice device_h,
427
struct wsi_swapchain *drv_chain,
428
const VkSwapchainCreateInfoKHR *create_info,
429
const VkAllocationCallbacks *allocator,
430
struct wsi_win32_image *image)
431
{
432
struct wsi_win32_swapchain *chain = (struct wsi_win32_swapchain *) drv_chain;
433
434
VkResult result = wsi_create_native_image(&chain->base, create_info,
435
0, NULL, NULL,
436
&image->base);
437
if (result != VK_SUCCESS)
438
return result;
439
440
VkIcdSurfaceWin32 *win32_surface = (VkIcdSurfaceWin32 *)create_info->surface;
441
chain->wnd = win32_surface->hwnd;
442
chain->chain_dc = GetDC(chain->wnd);
443
444
image->dc = CreateCompatibleDC(chain->chain_dc);
445
HBITMAP bmp = NULL;
446
447
BITMAPINFO info = { 0 };
448
info.bmiHeader.biSize = sizeof(BITMAPINFO);
449
info.bmiHeader.biWidth = create_info->imageExtent.width;
450
info.bmiHeader.biHeight = -create_info->imageExtent.height;
451
info.bmiHeader.biPlanes = 1;
452
info.bmiHeader.biBitCount = 32;
453
info.bmiHeader.biCompression = BI_RGB;
454
455
bmp = CreateDIBSection(image->dc, &info, DIB_RGB_COLORS, &image->ppvBits, NULL, 0);
456
assert(bmp && image->ppvBits);
457
458
SelectObject(image->dc, bmp);
459
460
BITMAP header;
461
int status = GetObject(bmp, sizeof(BITMAP), &header);
462
(void)status;
463
image->bmp_row_pitch = header.bmWidthBytes;
464
image->bmp = bmp;
465
image->chain = chain;
466
467
return VK_SUCCESS;
468
}
469
470
static void
471
wsi_win32_image_finish(struct wsi_swapchain *drv_chain,
472
const VkAllocationCallbacks *allocator,
473
struct wsi_win32_image *image)
474
{
475
struct wsi_win32_swapchain *chain =
476
(struct wsi_win32_swapchain *) drv_chain;
477
478
DeleteDC(image->dc);
479
if(image->bmp)
480
DeleteObject(image->bmp);
481
wsi_destroy_image(&chain->base, &image->base);
482
}
483
484
static VkResult
485
wsi_win32_swapchain_destroy(struct wsi_swapchain *drv_chain,
486
const VkAllocationCallbacks *allocator)
487
{
488
struct wsi_win32_swapchain *chain =
489
(struct wsi_win32_swapchain *) drv_chain;
490
491
for (uint32_t i = 0; i < chain->base.image_count; i++)
492
wsi_win32_image_finish(drv_chain, allocator, &chain->images[i]);
493
494
DeleteDC(chain->chain_dc);
495
496
wsi_swapchain_finish(&chain->base);
497
vk_free(allocator, chain);
498
return VK_SUCCESS;
499
}
500
501
static struct wsi_image *
502
wsi_win32_get_wsi_image(struct wsi_swapchain *drv_chain,
503
uint32_t image_index)
504
{
505
struct wsi_win32_swapchain *chain =
506
(struct wsi_win32_swapchain *) drv_chain;
507
508
return &chain->images[image_index].base;
509
}
510
511
static VkResult
512
wsi_win32_acquire_next_image(struct wsi_swapchain *drv_chain,
513
const VkAcquireNextImageInfoKHR *info,
514
uint32_t *image_index)
515
{
516
struct wsi_win32_swapchain *chain =
517
(struct wsi_win32_swapchain *)drv_chain;
518
519
/* Bail early if the swapchain is broken */
520
if (chain->status != VK_SUCCESS)
521
return chain->status;
522
523
*image_index = 0;
524
return VK_SUCCESS;
525
}
526
527
static VkResult
528
wsi_win32_queue_present(struct wsi_swapchain *drv_chain,
529
uint32_t image_index,
530
const VkPresentRegionKHR *damage)
531
{
532
struct wsi_win32_swapchain *chain = (struct wsi_win32_swapchain *) drv_chain;
533
assert(image_index < chain->base.image_count);
534
struct wsi_win32_image *image = &chain->images[image_index];
535
VkResult result;
536
537
char *ptr;
538
char *dptr = image->ppvBits;
539
result = chain->base.wsi->MapMemory(chain->base.device,
540
image->base.memory,
541
0, image->base.sizes[0], 0, (void**)&ptr);
542
543
for (unsigned h = 0; h < chain->extent.height; h++) {
544
memcpy(dptr, ptr, chain->extent.width * 4);
545
dptr += image->bmp_row_pitch;
546
ptr += image->base.row_pitches[0];
547
}
548
if(StretchBlt(chain->chain_dc, 0, 0, chain->extent.width, chain->extent.height, image->dc, 0, 0, chain->extent.width, chain->extent.height, SRCCOPY))
549
result = VK_SUCCESS;
550
else
551
result = VK_ERROR_MEMORY_MAP_FAILED;
552
553
chain->base.wsi->UnmapMemory(chain->base.device, image->base.memory);
554
if (result != VK_SUCCESS)
555
chain->status = result;
556
557
if (result != VK_SUCCESS)
558
return result;
559
560
return chain->status;
561
}
562
563
static VkResult
564
wsi_win32_surface_create_swapchain(
565
VkIcdSurfaceBase *icd_surface,
566
VkDevice device,
567
struct wsi_device *wsi_device,
568
const VkSwapchainCreateInfoKHR *create_info,
569
const VkAllocationCallbacks *allocator,
570
struct wsi_swapchain **swapchain_out)
571
{
572
VkIcdSurfaceWin32 *surface = (VkIcdSurfaceWin32 *)icd_surface;
573
struct wsi_win32 *wsi =
574
(struct wsi_win32 *) wsi_device->wsi[VK_ICD_WSI_PLATFORM_WIN32];
575
576
assert(create_info->sType == VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR);
577
578
const unsigned num_images = create_info->minImageCount;
579
struct wsi_win32_swapchain *chain;
580
size_t size = sizeof(*chain) + num_images * sizeof(chain->images[0]);
581
582
chain = vk_zalloc(allocator, size,
583
8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
584
585
if (chain == NULL)
586
return VK_ERROR_OUT_OF_HOST_MEMORY;
587
588
VkResult result = wsi_swapchain_init(wsi_device, &chain->base, device,
589
create_info, allocator);
590
if (result != VK_SUCCESS) {
591
vk_free(allocator, chain);
592
return result;
593
}
594
595
chain->base.destroy = wsi_win32_swapchain_destroy;
596
chain->base.get_wsi_image = wsi_win32_get_wsi_image;
597
chain->base.acquire_next_image = wsi_win32_acquire_next_image;
598
chain->base.queue_present = wsi_win32_queue_present;
599
chain->base.present_mode = wsi_swapchain_get_present_mode(wsi_device, create_info);
600
chain->base.image_count = num_images;
601
chain->extent = create_info->imageExtent;
602
603
chain->wsi = wsi;
604
chain->status = VK_SUCCESS;
605
606
chain->surface = surface;
607
608
for (uint32_t image = 0; image < chain->base.image_count; image++) {
609
result = wsi_win32_image_init(device, &chain->base,
610
create_info, allocator,
611
&chain->images[image]);
612
if (result != VK_SUCCESS) {
613
while (image > 0) {
614
--image;
615
wsi_win32_image_finish(&chain->base, allocator,
616
&chain->images[image]);
617
}
618
vk_free(allocator, chain);
619
goto fail_init_images;
620
}
621
}
622
623
*swapchain_out = &chain->base;
624
625
return VK_SUCCESS;
626
627
fail_init_images:
628
return result;
629
}
630
631
632
VkResult
633
wsi_win32_init_wsi(struct wsi_device *wsi_device,
634
const VkAllocationCallbacks *alloc,
635
VkPhysicalDevice physical_device)
636
{
637
struct wsi_win32 *wsi;
638
VkResult result;
639
640
wsi = vk_alloc(alloc, sizeof(*wsi), 8,
641
VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
642
if (!wsi) {
643
result = VK_ERROR_OUT_OF_HOST_MEMORY;
644
goto fail;
645
}
646
647
wsi->physical_device = physical_device;
648
wsi->alloc = alloc;
649
wsi->wsi = wsi_device;
650
651
wsi->base.get_support = wsi_win32_surface_get_support;
652
wsi->base.get_capabilities2 = wsi_win32_surface_get_capabilities2;
653
wsi->base.get_formats = wsi_win32_surface_get_formats;
654
wsi->base.get_formats2 = wsi_win32_surface_get_formats2;
655
wsi->base.get_present_modes = wsi_win32_surface_get_present_modes;
656
wsi->base.get_present_rectangles = wsi_win32_surface_get_present_rectangles;
657
wsi->base.create_swapchain = wsi_win32_surface_create_swapchain;
658
659
wsi_device->wsi[VK_ICD_WSI_PLATFORM_WIN32] = &wsi->base;
660
661
return VK_SUCCESS;
662
663
fail:
664
wsi_device->wsi[VK_ICD_WSI_PLATFORM_WIN32] = NULL;
665
666
return result;
667
}
668
669
void
670
wsi_win32_finish_wsi(struct wsi_device *wsi_device,
671
const VkAllocationCallbacks *alloc)
672
{
673
struct wsi_win32 *wsi =
674
(struct wsi_win32 *)wsi_device->wsi[VK_ICD_WSI_PLATFORM_WIN32];
675
if (!wsi)
676
return;
677
678
vk_free(alloc, wsi);
679
}
680
681