/* * Copyright 2022 Google LLC * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include "tools/graphite/vk/GraphiteVulkanTestContext.h" #include "include/gpu/graphite/Context.h" #include "include/gpu/graphite/ContextOptions.h" #include "include/gpu/graphite/vk/VulkanGraphiteUtils.h" #include "include/gpu/vk/VulkanExtensions.h" #include "include/gpu/vk/VulkanMemoryAllocator.h" #include "src/gpu/graphite/ContextOptionsPriv.h" #include "tools/gpu/ContextType.h" #include "tools/gpu/vk/VkTestUtils.h" #include "tools/graphite/TestOptions.h" extern bool gCreateProtectedContext; namespace skiatest::graphite { std::unique_ptr VulkanTestContext::Make() { skgpu::VulkanBackendContext backendContext; skgpu::VulkanExtensions* extensions; VkPhysicalDeviceFeatures2* features; VkDebugReportCallbackEXT debugCallback = VK_NULL_HANDLE; PFN_vkDestroyDebugReportCallbackEXT destroyCallback = nullptr; PFN_vkGetInstanceProcAddr instProc; if (!sk_gpu_test::LoadVkLibraryAndGetProcAddrFuncs(&instProc)) { return nullptr; } extensions = new skgpu::VulkanExtensions(); features = new VkPhysicalDeviceFeatures2; memset(features, 0, sizeof(VkPhysicalDeviceFeatures2)); if (!sk_gpu_test::CreateVkBackendContext(instProc, &backendContext, extensions, features, &debugCallback, nullptr, sk_gpu_test::CanPresentFn(), gCreateProtectedContext)) { sk_gpu_test::FreeVulkanFeaturesStructs(features); delete features; delete extensions; return nullptr; } if (debugCallback != VK_NULL_HANDLE) { destroyCallback = (PFN_vkDestroyDebugReportCallbackEXT) instProc( backendContext.fInstance, "vkDestroyDebugReportCallbackEXT"); } return std::unique_ptr(new VulkanTestContext(backendContext, extensions, features, debugCallback, destroyCallback)); } #define ACQUIRE_VK_PROC_LOCAL(name, inst) \ PFN_vk##name localVk##name = \ reinterpret_cast(fVulkan.fGetProc("vk" #name, inst, nullptr)); \ do { \ if (localVk##name == nullptr) { \ SkDebugf("Function ptr for vk%s could not be acquired\n", #name); \ return; \ } \ } while (0) VulkanTestContext::~VulkanTestContext() { fVulkan.fMemoryAllocator.reset(); ACQUIRE_VK_PROC_LOCAL(DeviceWaitIdle, fVulkan.fInstance); ACQUIRE_VK_PROC_LOCAL(DestroyDevice, fVulkan.fInstance); ACQUIRE_VK_PROC_LOCAL(DestroyInstance, fVulkan.fInstance); localVkDeviceWaitIdle(fVulkan.fDevice); localVkDestroyDevice(fVulkan.fDevice, nullptr); #ifdef SK_ENABLE_VK_LAYERS if (fDebugCallback != VK_NULL_HANDLE) { fDestroyDebugReportCallbackEXT(fVulkan.fInstance, fDebugCallback, nullptr); } #else // Surpress unused private member variable warning (void)fDebugCallback; (void)fDestroyDebugReportCallbackEXT; #endif localVkDestroyInstance(fVulkan.fInstance, nullptr); delete fExtensions; sk_gpu_test::FreeVulkanFeaturesStructs(fFeatures); delete fFeatures; } skgpu::ContextType VulkanTestContext::contextType() { return skgpu::ContextType::kVulkan; } std::unique_ptr VulkanTestContext::makeContext( const TestOptions& options) { SkASSERT(!options.hasDawnOptions()); skgpu::graphite::ContextOptions revisedContextOptions(options.fContextOptions); skgpu::graphite::ContextOptionsPriv contextOptionsPriv; if (!options.fContextOptions.fOptionsPriv) { revisedContextOptions.fOptionsPriv = &contextOptionsPriv; } // Needed to make synchronous readPixels work revisedContextOptions.fOptionsPriv->fStoreContextRefInRecorder = true; SkASSERT(fVulkan.fMemoryAllocator); return skgpu::graphite::ContextFactory::MakeVulkan(fVulkan, revisedContextOptions); } } // namespace skiatest::graphite