35 {
36
37VulkanWindowContext::VulkanWindowContext(
const DisplayParams&
params,
38 CreateVkSurfaceFn createVkSurface,
39 CanPresentFn canPresent,
42 , fCreateVkSurfaceFn(
std::move(createVkSurface))
43 , fCanPresentFn(
std::move(canPresent))
46 , fImages(nullptr)
47 , fImageLayouts(nullptr)
48 , fSurfaces(nullptr)
49 , fBackbuffers(nullptr) {
50 fGetInstanceProcAddr = instProc;
51 this->initializeContext();
52}
53
54void VulkanWindowContext::initializeContext() {
56
57
62 if (!sk_gpu_test::CreateVkBackendContext(getInstanceProc, &backendContext, &extensions,
63 &features, &fDebugCallback, &fPresentQueueIndex,
64 fCanPresentFn,
65 fDisplayParams.fCreateProtectedNativeBackend)) {
66 sk_gpu_test::FreeVulkanFeaturesStructs(&features);
67 return;
68 }
69
72 sk_gpu_test::FreeVulkanFeaturesStructs(&features);
73 return;
74 }
75
78 fDevice = backendContext.
fDevice;
80 fGraphicsQueue = backendContext.
fQueue;
81
84 backendContext.
fGetProc(
"vkGetPhysicalDeviceProperties",
87 if (!localGetPhysicalDeviceProperties) {
88 sk_gpu_test::FreeVulkanFeaturesStructs(&features);
89 return;
90 }
92 localGetPhysicalDeviceProperties(backendContext.
fPhysicalDevice, &physDeviceProperties);
93 uint32_t physDevVersion = physDeviceProperties.
apiVersion;
94
97 &extensions));
98
101 GET_PROC(DestroyDebugReportCallbackEXT);
102 }
104 GET_PROC(GetPhysicalDeviceSurfaceSupportKHR);
105 GET_PROC(GetPhysicalDeviceSurfaceCapabilitiesKHR);
106 GET_PROC(GetPhysicalDeviceSurfaceFormatsKHR);
107 GET_PROC(GetPhysicalDeviceSurfacePresentModesKHR);
117
119
120 fSurface = fCreateVkSurfaceFn(fInstance);
122 this->destroyContext();
123 sk_gpu_test::FreeVulkanFeaturesStructs(&features);
124 return;
125 }
126
128 VkResult res = fGetPhysicalDeviceSurfaceSupportKHR(fPhysicalDevice, fPresentQueueIndex,
129 fSurface, &supported);
131 this->destroyContext();
132 sk_gpu_test::FreeVulkanFeaturesStructs(&features);
133 return;
134 }
135
136 if (!this->createSwapchain(-1, -1, fDisplayParams)) {
137 this->destroyContext();
138 sk_gpu_test::FreeVulkanFeaturesStructs(&features);
139 return;
140 }
141
142
143 fGetDeviceQueue(fDevice, fPresentQueueIndex, 0, &fPresentQueue);
144 sk_gpu_test::FreeVulkanFeaturesStructs(&features);
145}
146
147bool VulkanWindowContext::createSwapchain(
int width,
int height,
148 const DisplayParams&
params) {
149
151 VkResult res = fGetPhysicalDeviceSurfaceCapabilitiesKHR(fPhysicalDevice, fSurface, &caps);
153 return false;
154 }
155
156 uint32_t surfaceFormatCount;
157 res = fGetPhysicalDeviceSurfaceFormatsKHR(fPhysicalDevice, fSurface, &surfaceFormatCount,
158 nullptr);
160 return false;
161 }
162
165 res = fGetPhysicalDeviceSurfaceFormatsKHR(fPhysicalDevice, fSurface, &surfaceFormatCount,
166 surfaceFormats);
168 return false;
169 }
170
171 uint32_t presentModeCount;
172 res = fGetPhysicalDeviceSurfacePresentModesKHR(fPhysicalDevice, fSurface, &presentModeCount,
173 nullptr);
175 return false;
176 }
177
180 res = fGetPhysicalDeviceSurfacePresentModesKHR(fPhysicalDevice, fSurface, &presentModeCount,
181 presentModes);
183 return false;
184 }
185
187
188 if (extent.
width == (uint32_t)-1) {
191 }
192
193
198 }
199
204 }
205
208
211
213 }
214
221 }
224 }
232
233
236 for (uint32_t i = 0; i < surfaceFormatCount; ++i) {
239 surfaceFormat = localFormat;
241 break;
242 }
243 }
245 fSampleCount = std::max(1,
params.fMSAASampleCount);
246 fStencilBits = 8;
247
249 return false;
250 }
251
253 switch (surfaceFormat) {
257 break;
260 break;
261 default:
262 return false;
263 }
264
265
266
268 bool hasImmediate = false;
269 for (uint32_t i = 0; i < presentModeCount; ++i) {
270
273 }
275 hasImmediate = true;
276 }
277 }
278 if (
params.fDisableVsync && hasImmediate) {
280 }
281
285 swapchainCreateInfo.
flags = fDisplayParams.fCreateProtectedNativeBackend
287 : 0;
288 swapchainCreateInfo.
surface = fSurface;
295
296 uint32_t queueFamilies[] = { fGraphicsQueueIndex, fPresentQueueIndex };
297 if (fGraphicsQueueIndex != fPresentQueueIndex) {
301 } else {
305 }
306
310 swapchainCreateInfo.
clipped =
true;
312
313 res = fCreateSwapchainKHR(fDevice, &swapchainCreateInfo, nullptr, &fSwapchain);
315 return false;
316 }
317
318
320 fDeviceWaitIdle(fDevice);
321
322 this->destroyBuffers();
323
324 fDestroySwapchainKHR(fDevice, swapchainCreateInfo.
oldSwapchain,
nullptr);
325 }
326
329 fDeviceWaitIdle(fDevice);
330
331 this->destroyBuffers();
332
333 fDestroySwapchainKHR(fDevice, swapchainCreateInfo.
oldSwapchain,
nullptr);
334 }
335
336 return true;
337}
338
343 fGetSwapchainImagesKHR(fDevice, fSwapchain, &fImageCount, nullptr);
345 fImages = new VkImage[fImageCount];
346 fGetSwapchainImagesKHR(fDevice, fSwapchain, &fImageCount, fImages);
347
348
351 for (uint32_t i = 0; i < fImageCount; ++i) {
353
360 info.fImageUsageFlags = usageFlags;
361 info.fLevelCount = 1;
362 info.fCurrentQueueFamily = fPresentQueueIndex;
364 info.fSharingMode = sharingMode;
365
369 backendTexture,
371 fDisplayParams.fMSAASampleCount,
373 fDisplayParams.fColorSpace,
374 &fDisplayParams.fSurfaceProps);
375 } else {
376 if (fDisplayParams.fMSAASampleCount > 1) {
377 return false;
378 }
379 info.fSampleCount = fSampleCount;
382 backendRT,
385 fDisplayParams.fColorSpace,
386 &fDisplayParams.fSurfaceProps);
387 }
388 if (!fSurfaces[i]) {
389 return false;
390 }
391 }
392
393
397 semaphoreInfo.
pNext =
nullptr;
398 semaphoreInfo.
flags = 0;
399
400
401
402 fBackbuffers = new BackbufferInfo[fImageCount + 1];
403 for (uint32_t i = 0; i < fImageCount + 1; ++i) {
404 fBackbuffers[i].fImageIndex = -1;
406 CreateSemaphore(fDevice, &semaphoreInfo, nullptr,
407 &fBackbuffers[i].fRenderSemaphore));
409 }
410 fCurrentBackbufferIndex = fImageCount;
411 return true;
412}
413
414void VulkanWindowContext::destroyBuffers() {
415
416 if (fBackbuffers) {
417 for (uint32_t i = 0; i < fImageCount + 1; ++i) {
418 fBackbuffers[i].fImageIndex = -1;
420 DestroySemaphore(fDevice,
421 fBackbuffers[i].fRenderSemaphore,
422 nullptr));
423 }
424 }
425
426 delete[] fBackbuffers;
427 fBackbuffers = nullptr;
428
429
430 delete[] fSurfaces;
431 fSurfaces = nullptr;
432 delete[] fImageLayouts;
433 fImageLayouts = nullptr;
434 delete[] fImages;
435 fImages = nullptr;
436}
437
438VulkanWindowContext::~VulkanWindowContext() {
439 this->destroyContext();
440}
441
442void VulkanWindowContext::destroyContext() {
443 if (this->isValid()) {
444 fQueueWaitIdle(fPresentQueue);
445 fDeviceWaitIdle(fDevice);
446
447 this->destroyBuffers();
448
450 fDestroySwapchainKHR(fDevice, fSwapchain, nullptr);
452 }
453
455 fDestroySurfaceKHR(fInstance, fSurface, nullptr);
457 }
458 }
459
462 fInterface.reset();
463
465 fDestroyDevice(fDevice, nullptr);
467 }
468
469#ifdef SK_ENABLE_VK_LAYERS
471 fDestroyDebugReportCallbackEXT(fInstance, fDebugCallback, nullptr);
472 }
473#endif
474
476
478 fDestroyInstance(fInstance, nullptr);
480 }
481}
482
483VulkanWindowContext::BackbufferInfo* VulkanWindowContext::getAvailableBackbuffer() {
485
486 ++fCurrentBackbufferIndex;
487 if (fCurrentBackbufferIndex > fImageCount) {
488 fCurrentBackbufferIndex = 0;
489 }
490
491 BackbufferInfo* backbuffer = fBackbuffers + fCurrentBackbufferIndex;
492 return backbuffer;
493}
494
496 BackbufferInfo* backbuffer = this->getAvailableBackbuffer();
498
499
503 semaphoreInfo.
pNext =
nullptr;
504 semaphoreInfo.
flags = 0;
505 VkSemaphore semaphore;
507 nullptr, &semaphore));
509
510
511 VkResult res = fAcquireNextImageKHR(fDevice, fSwapchain, UINT64_MAX,
513 &backbuffer->fImageIndex);
515
516
517 GR_VK_CALL(fInterface, DestroySemaphore(fDevice, semaphore,
nullptr));
518 return nullptr;
519 }
521
522 if (!this->createSwapchain(-1, -1, fDisplayParams)) {
523 GR_VK_CALL(fInterface, DestroySemaphore(fDevice, semaphore,
nullptr));
524 return nullptr;
525 }
526 backbuffer = this->getAvailableBackbuffer();
527
528
529 res = fAcquireNextImageKHR(fDevice, fSwapchain, UINT64_MAX,
531 &backbuffer->fImageIndex);
532
534 GR_VK_CALL(fInterface, DestroySemaphore(fDevice, semaphore,
nullptr));
535 return nullptr;
536 }
537 }
538
540
542
543 surface->wait(1, &beSemaphore);
544
546}
547
548void VulkanWindowContext::onSwapBuffers() {
549
550 BackbufferInfo* backbuffer = fBackbuffers + fCurrentBackbufferIndex;
552
554
557 info.fSignalSemaphores = &beSemaphore;
560 auto dContext =
surface->recordingContext()->asDirectContext();
562 dContext->submit();
563
564
566 {
568 nullptr,
569 1,
570 &backbuffer->fRenderSemaphore,
571 1,
572 &fSwapchain,
573 &backbuffer->fImageIndex,
574 nullptr
575 };
576
577 fQueuePresentKHR(fPresentQueue, &presentInfo);
578}
579
580}
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
@ kTopLeft_GrSurfaceOrigin
bool GrVkFormatIsSupported(VkFormat format)
#define GR_VK_CALL(IFACE, X)
@ 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)
Type::kYUV Type::kRGBA() int(0.7 *637)
const EmbeddedViewParams * params
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)
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)
uint32_t fInstanceVersion
VkPhysicalDevice fPhysicalDevice
uint32_t fGraphicsQueueIndex
skgpu::VulkanGetProc fGetProc
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
@ 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_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