Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
VulkanWindowContext.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2023 Google LLC
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
9
25
26#ifdef VK_USE_PLATFORM_WIN32_KHR
27// windows wants to define this as CreateSemaphoreA or CreateSemaphoreW
28#undef CreateSemaphore
29#endif
30
31#define GET_PROC(F) f ## F = \
32 (PFN_vk ## F) backendContext.fGetProc("vk" #F, fInstance, VK_NULL_HANDLE)
33#define GET_DEV_PROC(F) f ## F = \
34 (PFN_vk ## F) backendContext.fGetProc("vk" #F, VK_NULL_HANDLE, fDevice)
35
36namespace skwindow::internal {
37
38VulkanWindowContext::VulkanWindowContext(const DisplayParams& params,
39 CreateVkSurfaceFn createVkSurface,
40 CanPresentFn canPresent,
42 : WindowContext(params)
43 , fCreateVkSurfaceFn(std::move(createVkSurface))
44 , fCanPresentFn(std::move(canPresent))
45 , fSurface(VK_NULL_HANDLE)
46 , fSwapchain(VK_NULL_HANDLE)
47 , fImages(nullptr)
48 , fImageLayouts(nullptr)
49 , fSurfaces(nullptr)
50 , fBackbuffers(nullptr) {
51 fGetInstanceProcAddr = instProc;
52 this->initializeContext();
53}
54
55void VulkanWindowContext::initializeContext() {
57 // any config code here (particularly for msaa)?
58
59 PFN_vkGetInstanceProcAddr getInstanceProc = fGetInstanceProcAddr;
60 GrVkBackendContext backendContext;
61 skgpu::VulkanExtensions extensions;
63 if (!sk_gpu_test::CreateVkBackendContext(getInstanceProc, &backendContext, &extensions,
64 &features, &fDebugCallback, &fPresentQueueIndex,
65 fCanPresentFn,
66 fDisplayParams.fCreateProtectedNativeBackend)) {
67 sk_gpu_test::FreeVulkanFeaturesStructs(&features);
68 return;
69 }
70
71 if (!extensions.hasExtension(VK_KHR_SURFACE_EXTENSION_NAME, 25) ||
72 !extensions.hasExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME, 68)) {
73 sk_gpu_test::FreeVulkanFeaturesStructs(&features);
74 return;
75 }
76
77 fInstance = backendContext.fInstance;
78 fPhysicalDevice = backendContext.fPhysicalDevice;
79 fDevice = backendContext.fDevice;
80 fGraphicsQueueIndex = backendContext.fGraphicsQueueIndex;
81 fGraphicsQueue = backendContext.fQueue;
82
83 PFN_vkGetPhysicalDeviceProperties localGetPhysicalDeviceProperties =
84 reinterpret_cast<PFN_vkGetPhysicalDeviceProperties>(
85 backendContext.fGetProc("vkGetPhysicalDeviceProperties",
86 backendContext.fInstance,
88 if (!localGetPhysicalDeviceProperties) {
89 sk_gpu_test::FreeVulkanFeaturesStructs(&features);
90 return;
91 }
92 VkPhysicalDeviceProperties physDeviceProperties;
93 localGetPhysicalDeviceProperties(backendContext.fPhysicalDevice, &physDeviceProperties);
94 uint32_t physDevVersion = physDeviceProperties.apiVersion;
95
96 fInterface.reset(new skgpu::VulkanInterface(backendContext.fGetProc, fInstance, fDevice,
97 backendContext.fInstanceVersion, physDevVersion,
98 &extensions));
99
100 GET_PROC(DestroyInstance);
101 if (fDebugCallback != VK_NULL_HANDLE) {
102 GET_PROC(DestroyDebugReportCallbackEXT);
103 }
104 GET_PROC(DestroySurfaceKHR);
105 GET_PROC(GetPhysicalDeviceSurfaceSupportKHR);
106 GET_PROC(GetPhysicalDeviceSurfaceCapabilitiesKHR);
107 GET_PROC(GetPhysicalDeviceSurfaceFormatsKHR);
108 GET_PROC(GetPhysicalDeviceSurfacePresentModesKHR);
109 GET_DEV_PROC(DeviceWaitIdle);
110 GET_DEV_PROC(QueueWaitIdle);
111 GET_DEV_PROC(DestroyDevice);
112 GET_DEV_PROC(CreateSwapchainKHR);
113 GET_DEV_PROC(DestroySwapchainKHR);
114 GET_DEV_PROC(GetSwapchainImagesKHR);
115 GET_DEV_PROC(AcquireNextImageKHR);
116 GET_DEV_PROC(QueuePresentKHR);
117 GET_DEV_PROC(GetDeviceQueue);
118
119 fContext = GrDirectContexts::MakeVulkan(backendContext, fDisplayParams.fGrContextOptions);
120
121 fSurface = fCreateVkSurfaceFn(fInstance);
122 if (VK_NULL_HANDLE == fSurface) {
123 this->destroyContext();
124 sk_gpu_test::FreeVulkanFeaturesStructs(&features);
125 return;
126 }
127
128 VkBool32 supported;
129 VkResult res = fGetPhysicalDeviceSurfaceSupportKHR(fPhysicalDevice, fPresentQueueIndex,
130 fSurface, &supported);
131 if (VK_SUCCESS != res) {
132 this->destroyContext();
133 sk_gpu_test::FreeVulkanFeaturesStructs(&features);
134 return;
135 }
136
137 if (!this->createSwapchain(-1, -1, fDisplayParams)) {
138 this->destroyContext();
139 sk_gpu_test::FreeVulkanFeaturesStructs(&features);
140 return;
141 }
142
143 // create presentQueue
144 fGetDeviceQueue(fDevice, fPresentQueueIndex, 0, &fPresentQueue);
145 sk_gpu_test::FreeVulkanFeaturesStructs(&features);
146}
147
148bool VulkanWindowContext::createSwapchain(int width, int height,
149 const DisplayParams& params) {
150 // check for capabilities
152 VkResult res = fGetPhysicalDeviceSurfaceCapabilitiesKHR(fPhysicalDevice, fSurface, &caps);
153 if (VK_SUCCESS != res) {
154 return false;
155 }
156
157 uint32_t surfaceFormatCount;
158 res = fGetPhysicalDeviceSurfaceFormatsKHR(fPhysicalDevice, fSurface, &surfaceFormatCount,
159 nullptr);
160 if (VK_SUCCESS != res) {
161 return false;
162 }
163
164 SkAutoMalloc surfaceFormatAlloc(surfaceFormatCount * sizeof(VkSurfaceFormatKHR));
165 VkSurfaceFormatKHR* surfaceFormats = (VkSurfaceFormatKHR*)surfaceFormatAlloc.get();
166 res = fGetPhysicalDeviceSurfaceFormatsKHR(fPhysicalDevice, fSurface, &surfaceFormatCount,
167 surfaceFormats);
168 if (VK_SUCCESS != res) {
169 return false;
170 }
171
172 uint32_t presentModeCount;
173 res = fGetPhysicalDeviceSurfacePresentModesKHR(fPhysicalDevice, fSurface, &presentModeCount,
174 nullptr);
175 if (VK_SUCCESS != res) {
176 return false;
177 }
178
179 SkAutoMalloc presentModeAlloc(presentModeCount * sizeof(VkPresentModeKHR));
180 VkPresentModeKHR* presentModes = (VkPresentModeKHR*)presentModeAlloc.get();
181 res = fGetPhysicalDeviceSurfacePresentModesKHR(fPhysicalDevice, fSurface, &presentModeCount,
182 presentModes);
183 if (VK_SUCCESS != res) {
184 return false;
185 }
186
187 VkExtent2D extent = caps.currentExtent;
188 // use the hints
189 if (extent.width == (uint32_t)-1) {
190 extent.width = width;
191 extent.height = height;
192 }
193
194 // clamp width; to protect us from broken hints
195 if (extent.width < caps.minImageExtent.width) {
196 extent.width = caps.minImageExtent.width;
197 } else if (extent.width > caps.maxImageExtent.width) {
198 extent.width = caps.maxImageExtent.width;
199 }
200 // clamp height
201 if (extent.height < caps.minImageExtent.height) {
202 extent.height = caps.minImageExtent.height;
203 } else if (extent.height > caps.maxImageExtent.height) {
204 extent.height = caps.maxImageExtent.height;
205 }
206
207 fWidth = (int)extent.width;
208 fHeight = (int)extent.height;
209
210 uint32_t imageCount = caps.minImageCount + 2;
211 if (caps.maxImageCount > 0 && imageCount > caps.maxImageCount) {
212 // Application must settle for fewer images than desired:
213 imageCount = caps.maxImageCount;
214 }
215
219 SkASSERT((caps.supportedUsageFlags & usageFlags) == usageFlags);
222 }
224 usageFlags |= VK_IMAGE_USAGE_SAMPLED_BIT;
225 }
229 VkCompositeAlphaFlagBitsKHR composite_alpha =
233
234 // Pick our surface format.
235 VkFormat surfaceFormat = VK_FORMAT_UNDEFINED;
237 for (uint32_t i = 0; i < surfaceFormatCount; ++i) {
238 VkFormat localFormat = surfaceFormats[i].format;
239 if (GrVkFormatIsSupported(localFormat)) {
240 surfaceFormat = localFormat;
241 colorSpace = surfaceFormats[i].colorSpace;
242 break;
243 }
244 }
245 fDisplayParams = params;
246 fSampleCount = std::max(1, params.fMSAASampleCount);
247 fStencilBits = 8;
248
249 if (VK_FORMAT_UNDEFINED == surfaceFormat) {
250 return false;
251 }
252
254 switch (surfaceFormat) {
255 case VK_FORMAT_R8G8B8A8_UNORM: // fall through
258 break;
259 case VK_FORMAT_B8G8R8A8_UNORM: // fall through
261 break;
262 default:
263 return false;
264 }
265
266 // If mailbox mode is available, use it, as it is the lowest-latency non-
267 // tearing mode. If not, fall back to FIFO which is always available.
269 bool hasImmediate = false;
270 for (uint32_t i = 0; i < presentModeCount; ++i) {
271 // use mailbox
272 if (VK_PRESENT_MODE_MAILBOX_KHR == presentModes[i]) {
274 }
275 if (VK_PRESENT_MODE_IMMEDIATE_KHR == presentModes[i]) {
276 hasImmediate = true;
277 }
278 }
279 if (params.fDisableVsync && hasImmediate) {
281 }
282
283 VkSwapchainCreateInfoKHR swapchainCreateInfo;
284 memset(&swapchainCreateInfo, 0, sizeof(VkSwapchainCreateInfoKHR));
286 swapchainCreateInfo.flags = fDisplayParams.fCreateProtectedNativeBackend
288 : 0;
289 swapchainCreateInfo.surface = fSurface;
290 swapchainCreateInfo.minImageCount = imageCount;
291 swapchainCreateInfo.imageFormat = surfaceFormat;
292 swapchainCreateInfo.imageColorSpace = colorSpace;
293 swapchainCreateInfo.imageExtent = extent;
294 swapchainCreateInfo.imageArrayLayers = 1;
295 swapchainCreateInfo.imageUsage = usageFlags;
296
297 uint32_t queueFamilies[] = { fGraphicsQueueIndex, fPresentQueueIndex };
298 if (fGraphicsQueueIndex != fPresentQueueIndex) {
299 swapchainCreateInfo.imageSharingMode = VK_SHARING_MODE_CONCURRENT;
300 swapchainCreateInfo.queueFamilyIndexCount = 2;
301 swapchainCreateInfo.pQueueFamilyIndices = queueFamilies;
302 } else {
303 swapchainCreateInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
304 swapchainCreateInfo.queueFamilyIndexCount = 0;
305 swapchainCreateInfo.pQueueFamilyIndices = nullptr;
306 }
307
309 swapchainCreateInfo.compositeAlpha = composite_alpha;
310 swapchainCreateInfo.presentMode = mode;
311 swapchainCreateInfo.clipped = true;
312 swapchainCreateInfo.oldSwapchain = fSwapchain;
313
314 res = fCreateSwapchainKHR(fDevice, &swapchainCreateInfo, nullptr, &fSwapchain);
315 if (VK_SUCCESS != res) {
316 return false;
317 }
318
319 // destroy the old swapchain
320 if (swapchainCreateInfo.oldSwapchain != VK_NULL_HANDLE) {
321 fDeviceWaitIdle(fDevice);
322
323 this->destroyBuffers();
324
325 fDestroySwapchainKHR(fDevice, swapchainCreateInfo.oldSwapchain, nullptr);
326 }
327
328 if (!this->createBuffers(swapchainCreateInfo.imageFormat, usageFlags, colorType,
329 swapchainCreateInfo.imageSharingMode)) {
330 fDeviceWaitIdle(fDevice);
331
332 this->destroyBuffers();
333
334 fDestroySwapchainKHR(fDevice, swapchainCreateInfo.oldSwapchain, nullptr);
335 }
336
337 return true;
338}
339
340bool VulkanWindowContext::createBuffers(VkFormat format,
341 VkImageUsageFlags usageFlags,
343 VkSharingMode sharingMode) {
344 fGetSwapchainImagesKHR(fDevice, fSwapchain, &fImageCount, nullptr);
345 SkASSERT(fImageCount);
346 fImages = new VkImage[fImageCount];
347 fGetSwapchainImagesKHR(fDevice, fSwapchain, &fImageCount, fImages);
348
349 // set up initial image layouts and create surfaces
350 fImageLayouts = new VkImageLayout[fImageCount];
351 fSurfaces = new sk_sp<SkSurface>[fImageCount];
352 for (uint32_t i = 0; i < fImageCount; ++i) {
353 fImageLayouts[i] = VK_IMAGE_LAYOUT_UNDEFINED;
354
356 info.fImage = fImages[i];
357 info.fAlloc = skgpu::VulkanAlloc();
358 info.fImageLayout = VK_IMAGE_LAYOUT_UNDEFINED;
359 info.fImageTiling = VK_IMAGE_TILING_OPTIMAL;
360 info.fFormat = format;
361 info.fImageUsageFlags = usageFlags;
362 info.fLevelCount = 1;
363 info.fCurrentQueueFamily = fPresentQueueIndex;
364 info.fProtected = skgpu::Protected(fDisplayParams.fCreateProtectedNativeBackend);
365 info.fSharingMode = sharingMode;
366
367 if (usageFlags & VK_IMAGE_USAGE_SAMPLED_BIT) {
368 GrBackendTexture backendTexture = GrBackendTextures::MakeVk(fWidth, fHeight, info);
369 fSurfaces[i] = SkSurfaces::WrapBackendTexture(fContext.get(),
370 backendTexture,
372 fDisplayParams.fMSAASampleCount,
373 colorType,
374 fDisplayParams.fColorSpace,
375 &fDisplayParams.fSurfaceProps);
376 } else {
377 if (fDisplayParams.fMSAASampleCount > 1) {
378 return false;
379 }
380 info.fSampleCount = fSampleCount;
381 GrBackendRenderTarget backendRT = GrBackendRenderTargets::MakeVk(fWidth, fHeight, info);
383 backendRT,
385 colorType,
386 fDisplayParams.fColorSpace,
387 &fDisplayParams.fSurfaceProps);
388 }
389 if (!fSurfaces[i]) {
390 return false;
391 }
392 }
393
394 // set up the backbuffers
395 VkSemaphoreCreateInfo semaphoreInfo;
396 memset(&semaphoreInfo, 0, sizeof(VkSemaphoreCreateInfo));
398 semaphoreInfo.pNext = nullptr;
399 semaphoreInfo.flags = 0;
400
401 // we create one additional backbuffer structure here, because we want to
402 // give the command buffers they contain a chance to finish before we cycle back
403 fBackbuffers = new BackbufferInfo[fImageCount + 1];
404 for (uint32_t i = 0; i < fImageCount + 1; ++i) {
405 fBackbuffers[i].fImageIndex = -1;
407 CreateSemaphore(fDevice, &semaphoreInfo, nullptr,
408 &fBackbuffers[i].fRenderSemaphore));
410 }
411 fCurrentBackbufferIndex = fImageCount;
412 return true;
413}
414
415void VulkanWindowContext::destroyBuffers() {
416
417 if (fBackbuffers) {
418 for (uint32_t i = 0; i < fImageCount + 1; ++i) {
419 fBackbuffers[i].fImageIndex = -1;
420 GR_VK_CALL(fInterface,
421 DestroySemaphore(fDevice,
422 fBackbuffers[i].fRenderSemaphore,
423 nullptr));
424 }
425 }
426
427 delete[] fBackbuffers;
428 fBackbuffers = nullptr;
429
430 // Does this actually free the surfaces?
431 delete[] fSurfaces;
432 fSurfaces = nullptr;
433 delete[] fImageLayouts;
434 fImageLayouts = nullptr;
435 delete[] fImages;
436 fImages = nullptr;
437}
438
439VulkanWindowContext::~VulkanWindowContext() {
440 this->destroyContext();
441}
442
443void VulkanWindowContext::destroyContext() {
444 if (this->isValid()) {
445 fQueueWaitIdle(fPresentQueue);
446 fDeviceWaitIdle(fDevice);
447
448 this->destroyBuffers();
449
450 if (VK_NULL_HANDLE != fSwapchain) {
451 fDestroySwapchainKHR(fDevice, fSwapchain, nullptr);
452 fSwapchain = VK_NULL_HANDLE;
453 }
454
455 if (VK_NULL_HANDLE != fSurface) {
456 fDestroySurfaceKHR(fInstance, fSurface, nullptr);
457 fSurface = VK_NULL_HANDLE;
458 }
459 }
460
461 SkASSERT(fContext->unique());
462 fContext.reset();
463 fInterface.reset();
464
465 if (VK_NULL_HANDLE != fDevice) {
466 fDestroyDevice(fDevice, nullptr);
467 fDevice = VK_NULL_HANDLE;
468 }
469
470#ifdef SK_ENABLE_VK_LAYERS
471 if (fDebugCallback != VK_NULL_HANDLE) {
472 fDestroyDebugReportCallbackEXT(fInstance, fDebugCallback, nullptr);
473 }
474#endif
475
476 fPhysicalDevice = VK_NULL_HANDLE;
477
478 if (VK_NULL_HANDLE != fInstance) {
479 fDestroyInstance(fInstance, nullptr);
480 fInstance = VK_NULL_HANDLE;
481 }
482}
483
484VulkanWindowContext::BackbufferInfo* VulkanWindowContext::getAvailableBackbuffer() {
485 SkASSERT(fBackbuffers);
486
487 ++fCurrentBackbufferIndex;
488 if (fCurrentBackbufferIndex > fImageCount) {
489 fCurrentBackbufferIndex = 0;
490 }
491
492 BackbufferInfo* backbuffer = fBackbuffers + fCurrentBackbufferIndex;
493 return backbuffer;
494}
495
496sk_sp<SkSurface> VulkanWindowContext::getBackbufferSurface() {
497 BackbufferInfo* backbuffer = this->getAvailableBackbuffer();
498 SkASSERT(backbuffer);
499
500 // semaphores should be in unsignaled state
501 VkSemaphoreCreateInfo semaphoreInfo;
502 memset(&semaphoreInfo, 0, sizeof(VkSemaphoreCreateInfo));
504 semaphoreInfo.pNext = nullptr;
505 semaphoreInfo.flags = 0;
506 VkSemaphore semaphore;
507 SkDEBUGCODE(VkResult result = )GR_VK_CALL(fInterface, CreateSemaphore(fDevice, &semaphoreInfo,
508 nullptr, &semaphore));
510
511 // acquire the image
512 VkResult res = fAcquireNextImageKHR(fDevice, fSwapchain, UINT64_MAX,
513 semaphore, VK_NULL_HANDLE,
514 &backbuffer->fImageIndex);
515 if (VK_ERROR_SURFACE_LOST_KHR == res) {
516 // need to figure out how to create a new vkSurface without the platformData*
517 // maybe use attach somehow? but need a Window
518 GR_VK_CALL(fInterface, DestroySemaphore(fDevice, semaphore, nullptr));
519 return nullptr;
520 }
521 if (VK_ERROR_OUT_OF_DATE_KHR == res) {
522 // tear swapchain down and try again
523 if (!this->createSwapchain(-1, -1, fDisplayParams)) {
524 GR_VK_CALL(fInterface, DestroySemaphore(fDevice, semaphore, nullptr));
525 return nullptr;
526 }
527 backbuffer = this->getAvailableBackbuffer();
528
529 // acquire the image
530 res = fAcquireNextImageKHR(fDevice, fSwapchain, UINT64_MAX,
531 semaphore, VK_NULL_HANDLE,
532 &backbuffer->fImageIndex);
533
534 if (VK_SUCCESS != res) {
535 GR_VK_CALL(fInterface, DestroySemaphore(fDevice, semaphore, nullptr));
536 return nullptr;
537 }
538 }
539
540 SkSurface* surface = fSurfaces[backbuffer->fImageIndex].get();
541
542 GrBackendSemaphore beSemaphore = GrBackendSemaphores::MakeVk(semaphore);
543
544 surface->wait(1, &beSemaphore);
545
546 return sk_ref_sp(surface);
547}
548
549void VulkanWindowContext::onSwapBuffers() {
550
551 BackbufferInfo* backbuffer = fBackbuffers + fCurrentBackbufferIndex;
552 SkSurface* surface = fSurfaces[backbuffer->fImageIndex].get();
553
554 GrBackendSemaphore beSemaphore = GrBackendSemaphores::MakeVk(backbuffer->fRenderSemaphore);
555
558 info.fSignalSemaphores = &beSemaphore;
560 VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, fPresentQueueIndex);
561 auto dContext = surface->recordingContext()->asDirectContext();
562 dContext->flush(surface, info, &presentState);
563 dContext->submit();
564
565 // Submit present operation to present queue
566 const VkPresentInfoKHR presentInfo =
567 {
569 nullptr, // pNext
570 1, // waitSemaphoreCount
571 &backbuffer->fRenderSemaphore, // pWaitSemaphores
572 1, // swapchainCount
573 &fSwapchain, // pSwapchains
574 &backbuffer->fImageIndex, // pImageIndices
575 nullptr // pResults
576 };
577
578 fQueuePresentKHR(fPresentQueue, &presentInfo);
579}
580
581} // namespace skwindow::internal
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition DM.cpp:213
@ kTopLeft_GrSurfaceOrigin
Definition GrTypes.h:148
bool GrVkFormatIsSupported(VkFormat format)
Definition GrVkUtil.cpp:21
#define GR_VK_CALL(IFACE, X)
Definition GrVkUtil.h:24
#define GET_DEV_PROC(F)
#define SkASSERT(cond)
Definition SkAssert.h:116
SkColorType
Definition SkColorType.h:19
@ kBGRA_8888_SkColorType
pixel with 8 bits for blue, green, red, alpha; in 32-bit word
Definition SkColorType.h:26
@ kRGBA_8888_SkColorType
pixel with 8 bits for red, green, blue, alpha; in 32-bit word
Definition SkColorType.h:24
#define SkDEBUGCODE(...)
Definition SkDebug.h:23
static SkColorType colorType(AImageDecoder *decoder, const AImageDecoderHeaderInfo *headerInfo)
sk_sp< T > sk_ref_sp(T *obj)
Definition SkRefCnt.h:381
const Context & fContext
Type::kYUV Type::kRGBA() int(0.7 *637)
void * get()
const EmbeddedViewParams * params
VkSurfaceKHR surface
Definition main.cc:49
GAsyncResult * result
uint32_t uint32_t * format
SK_API GrBackendRenderTarget MakeVk(int width, int height, const GrVkImageInfo &)
SK_API GrBackendSemaphore MakeVk(VkSemaphore semaphore)
SK_API GrBackendTexture MakeVk(int width, int height, const GrVkImageInfo &, std::string_view label={})
SK_API sk_sp< GrDirectContext > MakeVulkan(const GrVkBackendContext &, const GrContextOptions &)
SK_API sk_sp< SkSurface > WrapBackendRenderTarget(GrRecordingContext *context, const GrBackendRenderTarget &backendRenderTarget, GrSurfaceOrigin origin, SkColorType colorType, sk_sp< SkColorSpace > colorSpace, const SkSurfaceProps *surfaceProps, RenderTargetReleaseProc releaseProc=nullptr, ReleaseContext releaseContext=nullptr)
SK_API sk_sp< SkSurface > WrapBackendTexture(GrRecordingContext *context, const GrBackendTexture &backendTexture, GrSurfaceOrigin origin, int sampleCnt, SkColorType colorType, sk_sp< SkColorSpace > colorSpace, const SkSurfaceProps *surfaceProps, TextureReleaseProc textureReleaseProc=nullptr, ReleaseContext releaseContext=nullptr)
SK_API MutableTextureState MakeVulkan(VkImageLayout layout, uint32_t queueFamilyIndex)
Protected
Definition GpuTypes.h:61
int32_t height
int32_t width
size_t fNumSemaphores
Definition GrTypes.h:217
VkPhysicalDevice fPhysicalDevice
skgpu::VulkanGetProc fGetProc
VkImage fImage
Definition GrVkTypes.h:26
uint32_t width
uint32_t height
VkStructureType sType
VkSemaphoreCreateFlags flags
VkSurfaceTransformFlagBitsKHR currentTransform
VkCompositeAlphaFlagsKHR supportedCompositeAlpha
VkSurfaceTransformFlagsKHR supportedTransforms
VkImageUsageFlags supportedUsageFlags
VkColorSpaceKHR colorSpace
VkPresentModeKHR presentMode
VkImageUsageFlags imageUsage
VkSharingMode imageSharingMode
VkSwapchainCreateFlagsKHR flags
VkSwapchainKHR oldSwapchain
VkColorSpaceKHR imageColorSpace
VkSurfaceTransformFlagBitsKHR preTransform
const uint32_t * pQueueFamilyIndices
VkCompositeAlphaFlagBitsKHR compositeAlpha
@ VK_SWAPCHAIN_CREATE_PROTECTED_BIT_KHR
VkImageLayout
@ VK_IMAGE_LAYOUT_PRESENT_SRC_KHR
@ VK_IMAGE_LAYOUT_UNDEFINED
VkSharingMode
@ VK_SHARING_MODE_CONCURRENT
@ VK_SHARING_MODE_EXCLUSIVE
VkFlags VkImageUsageFlags
@ VK_IMAGE_TILING_OPTIMAL
#define VK_KHR_SURFACE_EXTENSION_NAME
void(VKAPI_PTR * PFN_vkGetPhysicalDeviceProperties)(VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties *pProperties)
@ VK_IMAGE_USAGE_TRANSFER_DST_BIT
@ VK_IMAGE_USAGE_SAMPLED_BIT
@ VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT
@ VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
@ VK_IMAGE_USAGE_TRANSFER_SRC_BIT
VkCompositeAlphaFlagBitsKHR
@ VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR
@ VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR
VkResult
@ VK_SUCCESS
@ VK_ERROR_OUT_OF_DATE_KHR
@ VK_ERROR_SURFACE_LOST_KHR
@ VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR
VkPresentModeKHR
@ VK_PRESENT_MODE_IMMEDIATE_KHR
@ VK_PRESENT_MODE_MAILBOX_KHR
@ VK_PRESENT_MODE_FIFO_KHR
#define VK_NULL_HANDLE
Definition vulkan_core.h:46
VkFormat
@ VK_FORMAT_R8G8B8A8_SRGB
@ VK_FORMAT_B8G8R8A8_UNORM
@ VK_FORMAT_R8G8B8A8_UNORM
@ VK_FORMAT_UNDEFINED
VkColorSpaceKHR
@ VK_COLORSPACE_SRGB_NONLINEAR_KHR
uint32_t VkBool32
Definition vulkan_core.h:94
#define VK_KHR_SWAPCHAIN_EXTENSION_NAME
PFN_vkVoidFunction(VKAPI_PTR * PFN_vkGetInstanceProcAddr)(VkInstance instance, const char *pName)
@ VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO
@ VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR
@ VK_STRUCTURE_TYPE_PRESENT_INFO_KHR