41 {
42
43GraphiteVulkanWindowContext::GraphiteVulkanWindowContext(
const DisplayParams&
params,
44 CreateVkSurfaceFn createVkSurface,
45 CanPresentFn canPresent,
48 , fCreateVkSurfaceFn(
std::move(createVkSurface))
49 , fCanPresentFn(
std::move(canPresent))
52 , fImages(nullptr)
53 , fImageLayouts(nullptr)
54 , fSurfaces(nullptr)
55 , fBackbuffers(nullptr) {
56 fGetInstanceProcAddr = instProc;
57 this->initializeContext();
58}
59
60void GraphiteVulkanWindowContext::initializeContext() {
61 SkASSERT(!fGraphiteContext && !fGraphiteRecorder);
62
63
68 if (!sk_gpu_test::CreateVkBackendContext(getInstanceProc, &backendContext, &extensions,
69 &features, &fDebugCallback, &fPresentQueueIndex,
70 fCanPresentFn,
71 fDisplayParams.fCreateProtectedNativeBackend)) {
72 sk_gpu_test::FreeVulkanFeaturesStructs(&features);
73 return;
74 }
75
78 sk_gpu_test::FreeVulkanFeaturesStructs(&features);
79 return;
80 }
81
84 fDevice = backendContext.
fDevice;
86 fGraphicsQueue = backendContext.
fQueue;
87
90 backendContext.
fGetProc(
"vkGetPhysicalDeviceProperties",
93 if (!localGetPhysicalDeviceProperties) {
94 sk_gpu_test::FreeVulkanFeaturesStructs(&features);
95 return;
96 }
98 localGetPhysicalDeviceProperties(backendContext.
fPhysicalDevice, &physDeviceProperties);
99 uint32_t physDevVersion = physDeviceProperties.
apiVersion;
100
103 &extensions));
104
107 GET_PROC(DestroyDebugReportCallbackEXT);
108 }
110 GET_PROC(GetPhysicalDeviceSurfaceSupportKHR);
111 GET_PROC(GetPhysicalDeviceSurfaceCapabilitiesKHR);
112 GET_PROC(GetPhysicalDeviceSurfaceFormatsKHR);
113 GET_PROC(GetPhysicalDeviceSurfacePresentModesKHR);
123
126
130 fGraphiteRecorder = fGraphiteContext->makeRecorder(ToolUtils::CreateTestingRecorderOptions());
131
132 fSurface = fCreateVkSurfaceFn(fInstance);
134 this->destroyContext();
135 sk_gpu_test::FreeVulkanFeaturesStructs(&features);
136 return;
137 }
138
140 VkResult res = fGetPhysicalDeviceSurfaceSupportKHR(fPhysicalDevice, fPresentQueueIndex,
141 fSurface, &supported);
143 this->destroyContext();
144 sk_gpu_test::FreeVulkanFeaturesStructs(&features);
145 return;
146 }
147
148 if (!this->createSwapchain(-1, -1, fDisplayParams)) {
149 this->destroyContext();
150 sk_gpu_test::FreeVulkanFeaturesStructs(&features);
151 return;
152 }
153
154
155 fGetDeviceQueue(fDevice, fPresentQueueIndex, 0, &fPresentQueue);
156 sk_gpu_test::FreeVulkanFeaturesStructs(&features);
157}
158
159bool GraphiteVulkanWindowContext::createSwapchain(
int width,
int height,
160 const DisplayParams&
params) {
161
163 VkResult res = fGetPhysicalDeviceSurfaceCapabilitiesKHR(fPhysicalDevice, fSurface, &caps);
165 return false;
166 }
167
168 uint32_t surfaceFormatCount;
169 res = fGetPhysicalDeviceSurfaceFormatsKHR(fPhysicalDevice, fSurface, &surfaceFormatCount,
170 nullptr);
172 return false;
173 }
174
177 res = fGetPhysicalDeviceSurfaceFormatsKHR(fPhysicalDevice, fSurface, &surfaceFormatCount,
178 surfaceFormats);
180 return false;
181 }
182
183 uint32_t presentModeCount;
184 res = fGetPhysicalDeviceSurfacePresentModesKHR(fPhysicalDevice, fSurface, &presentModeCount,
185 nullptr);
187 return false;
188 }
189
192 res = fGetPhysicalDeviceSurfacePresentModesKHR(fPhysicalDevice, fSurface, &presentModeCount,
193 presentModes);
195 return false;
196 }
197
199
200 if (extent.
width == (uint32_t)-1) {
203 }
204
205
210 }
211
216 }
217
220
223
225 }
226
233 }
236 }
244
245
248 for (uint32_t i = 0; i < surfaceFormatCount; ++i) {
251 surfaceFormat = localFormat;
253 break;
254 }
255 }
257 fSampleCount = std::max(1,
params.fMSAASampleCount);
258 fStencilBits = 8;
259
261 return false;
262 }
263
265 switch (surfaceFormat) {
269 break;
272 break;
273 default:
274 return false;
275 }
276
277
278
280 bool hasImmediate = false;
281 for (uint32_t i = 0; i < presentModeCount; ++i) {
282
285 }
287 hasImmediate = true;
288 }
289 }
290 if (
params.fDisableVsync && hasImmediate) {
292 }
293
297 swapchainCreateInfo.
flags = fDisplayParams.fCreateProtectedNativeBackend
299 : 0;
300 swapchainCreateInfo.
surface = fSurface;
307
308 uint32_t queueFamilies[] = { fGraphicsQueueIndex, fPresentQueueIndex };
309 if (fGraphicsQueueIndex != fPresentQueueIndex) {
313 } else {
317 }
318
322 swapchainCreateInfo.
clipped =
true;
324
325 res = fCreateSwapchainKHR(fDevice, &swapchainCreateInfo, nullptr, &fSwapchain);
327 return false;
328 }
329
330
332 fDeviceWaitIdle(fDevice);
333
334 this->destroyBuffers();
335
336 fDestroySwapchainKHR(fDevice, swapchainCreateInfo.
oldSwapchain,
nullptr);
338 }
339
342 fDeviceWaitIdle(fDevice);
343
344 this->destroyBuffers();
345
346 fDestroySwapchainKHR(fDevice, swapchainCreateInfo.
oldSwapchain,
nullptr);
348 }
349
350 return true;
351}
352
357 fGetSwapchainImagesKHR(fDevice, fSwapchain, &fImageCount, nullptr);
359 fImages = new VkImage[fImageCount];
360 fGetSwapchainImagesKHR(fDevice, fSwapchain, &fImageCount, fImages);
361
362
365 for (uint32_t i = 0; i < fImageCount; ++i) {
367
371 info.fImageUsageFlags = usageFlags;
372 info.fSharingMode = sharingMode;
374 : 0;
375
379 fPresentQueueIndex,
380 fImages[i],
382
384 backendTex,
386 fDisplayParams.fColorSpace,
387 &fDisplayParams.fSurfaceProps);
388
389 if (!fSurfaces[i]) {
390 return false;
391 }
392 }
393
394
398 semaphoreInfo.
pNext =
nullptr;
399 semaphoreInfo.
flags = 0;
400
401
402
403 fBackbuffers = new BackbufferInfo[fImageCount + 1];
404 for (uint32_t i = 0; i < fImageCount + 1; ++i) {
405 fBackbuffers[i].fImageIndex = -1;
408 fInterface,
410 CreateSemaphore(
411 fDevice, &semaphoreInfo, nullptr, &fBackbuffers[i].fRenderSemaphore));
412 }
413 fCurrentBackbufferIndex = fImageCount;
414
415 return true;
416}
417
418void GraphiteVulkanWindowContext::destroyBuffers() {
419 if (fBackbuffers) {
420 for (uint32_t i = 0; i < fImageCount + 1; ++i) {
421 fBackbuffers[i].fImageIndex = -1;
423 DestroySemaphore(fDevice,
424 fBackbuffers[i].fRenderSemaphore,
425 nullptr));
426 }
427 }
428
429 delete[] fBackbuffers;
430 fBackbuffers = nullptr;
431
432
433 delete[] fSurfaces;
434 fSurfaces = nullptr;
435 delete[] fImageLayouts;
436 fImageLayouts = nullptr;
437 delete[] fImages;
438 fImages = nullptr;
439}
440
441GraphiteVulkanWindowContext::~GraphiteVulkanWindowContext() {
442 this->destroyContext();
443}
444
445void GraphiteVulkanWindowContext::destroyContext() {
446 if (this->isValid()) {
447 fQueueWaitIdle(fPresentQueue);
448 fDeviceWaitIdle(fDevice);
449
451 VULKAN_CALL(fInterface, DestroySemaphore(fDevice, fWaitSemaphore,
nullptr));
453 }
454
455 this->destroyBuffers();
456
458 fDestroySwapchainKHR(fDevice, fSwapchain, nullptr);
460 }
461
463 fDestroySurfaceKHR(fInstance, fSurface, nullptr);
465 }
466 }
467
468 if (fGraphiteContext) {
469 fGraphiteRecorder.reset();
470 fGraphiteContext.reset();
471 }
472 fInterface.reset();
473
475 fDestroyDevice(fDevice, nullptr);
477 }
478
479#ifdef SK_ENABLE_VK_LAYERS
481 fDestroyDebugReportCallbackEXT(fInstance, fDebugCallback, nullptr);
482 }
483#endif
484
486
488 fDestroyInstance(fInstance, nullptr);
490 }
491}
492
493GraphiteVulkanWindowContext::BackbufferInfo* GraphiteVulkanWindowContext::getAvailableBackbuffer() {
495
496 ++fCurrentBackbufferIndex;
497 if (fCurrentBackbufferIndex > fImageCount) {
498 fCurrentBackbufferIndex = 0;
499 }
500
501 BackbufferInfo* backbuffer = fBackbuffers + fCurrentBackbufferIndex;
502 return backbuffer;
503}
504
506 BackbufferInfo* backbuffer = this->getAvailableBackbuffer();
508
509
513 semaphoreInfo.
pNext =
nullptr;
514 semaphoreInfo.
flags = 0;
517 fInterface,
result, CreateSemaphore(fDevice, &semaphoreInfo,
nullptr, &fWaitSemaphore));
518
519
520 VkResult res = fAcquireNextImageKHR(fDevice, fSwapchain, UINT64_MAX,
522 &backbuffer->fImageIndex);
524
525 VULKAN_CALL(fInterface, DestroySemaphore(fDevice, fWaitSemaphore,
nullptr));
526 return nullptr;
527 }
529
530 if (!this->createSwapchain(-1, -1, fDisplayParams)) {
531 VULKAN_CALL(fInterface, DestroySemaphore(fDevice, fWaitSemaphore,
nullptr));
532 return nullptr;
533 }
534 backbuffer = this->getAvailableBackbuffer();
535
536
537 res = fAcquireNextImageKHR(fDevice, fSwapchain, UINT64_MAX,
539 &backbuffer->fImageIndex);
540
542 VULKAN_CALL(fInterface, DestroySemaphore(fDevice, fWaitSemaphore,
nullptr));
543 return nullptr;
544 }
545 }
546
548
550}
551
552void GraphiteVulkanWindowContext::onSwapBuffers() {
553 if (!fGraphiteContext) {
554 return;
555 }
557
558 BackbufferInfo* backbuffer = fBackbuffers + fCurrentBackbufferIndex;
559
560 std::unique_ptr<skgpu::graphite::Recording> recording = fGraphiteRecorder->snap();
561 if (recording) {
564
565
566 info.fTargetSurface = fSurfaces[backbuffer->fImageIndex].get();
569 info.fTargetTextureState = &presentState;
570
573 info.fNumWaitSemaphores = 1;
574 info.fWaitSemaphores = &beWaitSemaphore;
576 info.fNumSignalSemaphores = 1;
577 info.fSignalSemaphores = &beSignalSemaphore;
578
579
580 struct FinishContext {
583 VkSemaphore waitSemaphore;
584 };
585 auto* finishContext = new FinishContext{fInterface, fDevice, fWaitSemaphore};
588
589 const auto* context = reinterpret_cast<const FinishContext*>(c);
591 DestroySemaphore(context->device, context->waitSemaphore, nullptr));
592 };
593 info.fFinishedContext = finishContext;
594 info.fFinishedProc = finishCallback;
595
596 fGraphiteContext->insertRecording(
info);
599 }
600
601
603 {
605 nullptr,
606 1,
607 &backbuffer->fRenderSemaphore,
608 1,
609 &fSwapchain,
610 &backbuffer->fImageIndex,
611 nullptr
612 };
613
614 fQueuePresentKHR(fPresentQueue, &presentInfo);
615}
616
617}
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
@ kBGRA_8888_SkColorType
pixel with 8 bits for blue, green, red, alpha; in 32-bit word
@ kRGBA_8888_SkColorType
pixel with 8 bits for red, green, blue, alpha; in 32-bit word
static SkColorType colorType(AImageDecoder *decoder, const AImageDecoderHeaderInfo *headerInfo)
sk_sp< T > sk_ref_sp(T *obj)
#define VULKAN_CALL(IFACE, X)
#define VULKAN_CALL_RESULT_NOCHECK(IFACE, RESULT, X)
Type::kYUV Type::kRGBA() int(0.7 *637)
const EmbeddedViewParams * params
uint32_t uint32_t * format
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)
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive mode
SK_API MutableTextureState MakeVulkan(VkImageLayout layout, uint32_t queueFamilyIndex)
SK_API std::unique_ptr< Context > MakeVulkan(const VulkanBackendContext &, const ContextOptions &)
bool vkFormatIsSupported(VkFormat format)
void * GpuFinishedContext
void(*)(GpuFinishedContext finishedContext, CallbackResult) GpuFinishedProc
VkSemaphoreCreateFlags flags
VkSurfaceTransformFlagBitsKHR currentTransform
VkCompositeAlphaFlagsKHR supportedCompositeAlpha
VkExtent2D maxImageExtent
VkExtent2D minImageExtent
VkSurfaceTransformFlagsKHR supportedTransforms
VkImageUsageFlags supportedUsageFlags
uint32_t imageArrayLayers
VkPresentModeKHR presentMode
VkImageUsageFlags imageUsage
VkSharingMode imageSharingMode
VkSwapchainCreateFlagsKHR flags
VkSwapchainKHR oldSwapchain
VkColorSpaceKHR imageColorSpace
uint32_t queueFamilyIndexCount
VkSurfaceTransformFlagBitsKHR preTransform
const uint32_t * pQueueFamilyIndices
VkCompositeAlphaFlagBitsKHR compositeAlpha
uint32_t fGraphicsQueueIndex
skgpu::VulkanGetProc fGetProc
VkPhysicalDevice fPhysicalDevice
bool fStoreContextRefInRecorder
ContextOptionsPriv * fOptionsPriv
VkImageTiling fImageTiling
@ VK_SWAPCHAIN_CREATE_PROTECTED_BIT_KHR
@ VK_IMAGE_LAYOUT_PRESENT_SRC_KHR
@ VK_IMAGE_LAYOUT_UNDEFINED
@ VK_SHARING_MODE_CONCURRENT
@ VK_SHARING_MODE_EXCLUSIVE
VkFlags VkImageUsageFlags
@ VK_IMAGE_CREATE_PROTECTED_BIT
@ 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
@ VK_ERROR_OUT_OF_DATE_KHR
@ VK_ERROR_SURFACE_LOST_KHR
@ VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR
@ VK_PRESENT_MODE_IMMEDIATE_KHR
@ VK_PRESENT_MODE_MAILBOX_KHR
@ VK_PRESENT_MODE_FIFO_KHR
@ VK_FORMAT_R8G8B8A8_SRGB
@ VK_FORMAT_B8G8R8A8_UNORM
@ VK_FORMAT_R8G8B8A8_UNORM
@ VK_COLORSPACE_SRGB_NONLINEAR_KHR
#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