Dynamically load the vulkan library in our test tools
Bug: skia: Change-Id: I7c1f6cbb2b50ca284f40cf4b9ef49a76083b38c6 Reviewed-on: https://skia-review.googlesource.com/68643 Reviewed-by: Chris Dalton <csmartdalton@google.com> Commit-Queue: Greg Daniel <egdaniel@google.com>
This commit is contained in:
parent
0f3c73220a
commit
77d6feaa69
18
BUILD.gn
18
BUILD.gn
@ -170,18 +170,6 @@ config("skia_private") {
|
||||
}
|
||||
libs = []
|
||||
lib_dirs = []
|
||||
if (skia_use_vulkan) {
|
||||
if (skia_vulkan_sdk != "" && !is_android && !is_fuchsia) {
|
||||
if (is_win) {
|
||||
lib_dirs += [
|
||||
"$skia_vulkan_sdk/Bin",
|
||||
"$skia_vulkan_sdk/Lib",
|
||||
]
|
||||
} else {
|
||||
lib_dirs += [ "$skia_vulkan_sdk/lib/" ]
|
||||
}
|
||||
}
|
||||
}
|
||||
if (skia_enable_gpu) {
|
||||
include_dirs += [ "src/gpu" ]
|
||||
}
|
||||
@ -1046,11 +1034,7 @@ if (skia_enable_tools) {
|
||||
}
|
||||
if (skia_use_vulkan) {
|
||||
sources += [ "tools/gpu/vk/VkTestContext.cpp" ]
|
||||
if (is_win) {
|
||||
libs += [ "vulkan-1.lib" ]
|
||||
} else {
|
||||
libs += [ "vulkan" ]
|
||||
}
|
||||
sources += [ "tools/gpu/vk/VkTestUtils.cpp" ]
|
||||
}
|
||||
if (skia_use_metal) {
|
||||
sources += [ "tools/gpu/mtl/MtlTestContext.mm" ]
|
||||
|
@ -10,9 +10,9 @@
|
||||
#ifdef SK_VULKAN
|
||||
|
||||
#include "GrContext.h"
|
||||
#include "VkTestUtils.h"
|
||||
#include "vk/GrVkInterface.h"
|
||||
#include "vk/GrVkUtil.h"
|
||||
#include <vulkan/vulkan.h>
|
||||
|
||||
namespace {
|
||||
/**
|
||||
@ -114,8 +114,12 @@ public:
|
||||
if (sharedContext) {
|
||||
backendContext = sharedContext->getVkBackendContext();
|
||||
} else {
|
||||
backendContext.reset(GrVkBackendContext::Create(vkGetInstanceProcAddr,
|
||||
vkGetDeviceProcAddr));
|
||||
PFN_vkGetInstanceProcAddr instProc;
|
||||
PFN_vkGetDeviceProcAddr devProc;
|
||||
if (!sk_gpu_test::LoadVkLibraryAndGetProcAddrFuncs(&instProc, &devProc)) {
|
||||
return nullptr;
|
||||
}
|
||||
backendContext.reset(GrVkBackendContext::Create(instProc, devProc));
|
||||
}
|
||||
if (!backendContext) {
|
||||
return nullptr;
|
||||
|
40
tools/gpu/vk/VkTestUtils.cpp
Normal file
40
tools/gpu/vk/VkTestUtils.cpp
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 2017 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "VkTestUtils.h"
|
||||
|
||||
#include "../ports/SkOSLibrary.h"
|
||||
|
||||
namespace sk_gpu_test {
|
||||
|
||||
bool LoadVkLibraryAndGetProcAddrFuncs(PFN_vkGetInstanceProcAddr* instProc,
|
||||
PFN_vkGetDeviceProcAddr* devProc) {
|
||||
static void* vkLib = nullptr;
|
||||
static PFN_vkGetInstanceProcAddr localInstProc = nullptr;
|
||||
static PFN_vkGetDeviceProcAddr localDevProc = nullptr;
|
||||
if (!vkLib) {
|
||||
#if defined _WIN32
|
||||
vkLib = DynamicLoadLibrary("vulkan-1.dll");
|
||||
#else
|
||||
vkLib = DynamicLoadLibrary("libvulkan.so");
|
||||
#endif
|
||||
if (!vkLib) {
|
||||
return false;
|
||||
}
|
||||
localInstProc = (PFN_vkGetInstanceProcAddr) GetProcedureAddress(vkLib,
|
||||
"vkGetInstanceProcAddr");
|
||||
localDevProc = (PFN_vkGetDeviceProcAddr) GetProcedureAddress(vkLib,
|
||||
"vkGetDeviceProcAddr");
|
||||
}
|
||||
if (!localInstProc || !localDevProc) {
|
||||
return false;
|
||||
}
|
||||
*instProc = localInstProc;
|
||||
*devProc = localDevProc;
|
||||
return true;
|
||||
}
|
||||
}
|
21
tools/gpu/vk/VkTestUtils.h
Normal file
21
tools/gpu/vk/VkTestUtils.h
Normal file
@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright 2017 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef VkTestUtils_DEFINED
|
||||
#define VkTestUtils_DEFINED
|
||||
|
||||
#ifdef SK_VULKAN
|
||||
|
||||
#include "vk/GrVkDefines.h"
|
||||
|
||||
namespace sk_gpu_test {
|
||||
bool LoadVkLibraryAndGetProcAddrFuncs(PFN_vkGetInstanceProcAddr*, PFN_vkGetDeviceProcAddr*);
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
@ -22,14 +22,16 @@
|
||||
#undef CreateSemaphore
|
||||
#endif
|
||||
|
||||
#define GET_PROC(F) f ## F = (PFN_vk ## F) vkGetInstanceProcAddr(instance, "vk" #F)
|
||||
#define GET_DEV_PROC(F) f ## F = (PFN_vk ## F) vkGetDeviceProcAddr(device, "vk" #F)
|
||||
#define GET_PROC(F) f ## F = (PFN_vk ## F) fGetInstanceProcAddr(instance, "vk" #F)
|
||||
#define GET_DEV_PROC(F) f ## F = (PFN_vk ## F) fGetDeviceProcAddr(device, "vk" #F)
|
||||
|
||||
namespace sk_app {
|
||||
|
||||
VulkanWindowContext::VulkanWindowContext(const DisplayParams& params,
|
||||
CreateVkSurfaceFn createVkSurface,
|
||||
CanPresentFn canPresent)
|
||||
CanPresentFn canPresent,
|
||||
PFN_vkGetInstanceProcAddr instProc,
|
||||
PFN_vkGetDeviceProcAddr devProc)
|
||||
: WindowContext(params)
|
||||
, fCreateVkSurfaceFn(createVkSurface)
|
||||
, fCanPresentFn(canPresent)
|
||||
@ -40,12 +42,14 @@ VulkanWindowContext::VulkanWindowContext(const DisplayParams& params,
|
||||
, fSurfaces(nullptr)
|
||||
, fCommandPool(VK_NULL_HANDLE)
|
||||
, fBackbuffers(nullptr) {
|
||||
fGetInstanceProcAddr = instProc;
|
||||
fGetDeviceProcAddr = devProc;
|
||||
this->initializeContext();
|
||||
}
|
||||
|
||||
void VulkanWindowContext::initializeContext() {
|
||||
// any config code here (particularly for msaa)?
|
||||
fBackendContext.reset(GrVkBackendContext::Create(vkGetInstanceProcAddr, vkGetDeviceProcAddr,
|
||||
fBackendContext.reset(GrVkBackendContext::Create(fGetInstanceProcAddr, fGetDeviceProcAddr,
|
||||
&fPresentQueueIndex, fCanPresentFn));
|
||||
|
||||
if (!(fBackendContext->fExtensions & kKHR_surface_GrVkExtensionFlag) ||
|
||||
@ -66,6 +70,7 @@ void VulkanWindowContext::initializeContext() {
|
||||
GET_DEV_PROC(GetSwapchainImagesKHR);
|
||||
GET_DEV_PROC(AcquireNextImageKHR);
|
||||
GET_DEV_PROC(QueuePresentKHR);
|
||||
GET_DEV_PROC(GetDeviceQueue);
|
||||
|
||||
fContext = GrContext::MakeVulkan(fBackendContext.get(), fDisplayParams.fGrContextOptions);
|
||||
|
||||
@ -90,7 +95,7 @@ void VulkanWindowContext::initializeContext() {
|
||||
}
|
||||
|
||||
// create presentQueue
|
||||
vkGetDeviceQueue(fBackendContext->fDevice, fPresentQueueIndex, 0, &fPresentQueue);
|
||||
fGetDeviceQueue(fBackendContext->fDevice, fPresentQueueIndex, 0, &fPresentQueue);
|
||||
}
|
||||
|
||||
bool VulkanWindowContext::createSwapchain(int width, int height,
|
||||
|
@ -47,7 +47,8 @@ public:
|
||||
/** Platform specific function that determines whether presentation will succeed. */
|
||||
using CanPresentFn = GrVkBackendContext::CanPresentFn;
|
||||
|
||||
VulkanWindowContext(const DisplayParams&, CreateVkSurfaceFn, CanPresentFn);
|
||||
VulkanWindowContext(const DisplayParams&, CreateVkSurfaceFn, CanPresentFn,
|
||||
PFN_vkGetInstanceProcAddr, PFN_vkGetDeviceProcAddr);
|
||||
|
||||
private:
|
||||
void initializeContext();
|
||||
@ -82,6 +83,10 @@ private:
|
||||
CreateVkSurfaceFn fCreateVkSurfaceFn;
|
||||
CanPresentFn fCanPresentFn;
|
||||
|
||||
// Vulkan GetProcAddr functions
|
||||
VkPtr<PFN_vkGetInstanceProcAddr> fGetInstanceProcAddr;
|
||||
VkPtr<PFN_vkGetDeviceProcAddr> fGetDeviceProcAddr;
|
||||
|
||||
// WSI interface functions
|
||||
VkPtr<PFN_vkDestroySurfaceKHR> fDestroySurfaceKHR;
|
||||
VkPtr<PFN_vkGetPhysicalDeviceSurfaceSupportKHR> fGetPhysicalDeviceSurfaceSupportKHR;
|
||||
@ -94,7 +99,7 @@ private:
|
||||
VkPtr<PFN_vkGetSwapchainImagesKHR> fGetSwapchainImagesKHR;
|
||||
VkPtr<PFN_vkAcquireNextImageKHR> fAcquireNextImageKHR;
|
||||
VkPtr<PFN_vkQueuePresentKHR> fQueuePresentKHR;
|
||||
VkPtr<PFN_vkCreateSharedSwapchainsKHR> fCreateSharedSwapchainsKHR;
|
||||
VkPtr<PFN_vkGetDeviceQueue> fGetDeviceQueue;
|
||||
|
||||
VkSurfaceKHR fSurface;
|
||||
VkSwapchainKHR fSwapchain;
|
||||
|
@ -9,15 +9,22 @@
|
||||
#include "WindowContextFactory_android.h"
|
||||
#include "../VulkanWindowContext.h"
|
||||
|
||||
#include "vk/VkTestUtils.h"
|
||||
|
||||
namespace sk_app {
|
||||
|
||||
namespace window_context_factory {
|
||||
|
||||
WindowContext* NewVulkanForAndroid(ANativeWindow* window, const DisplayParams& params) {
|
||||
auto createVkSurface = [window] (VkInstance instance) -> VkSurfaceKHR {
|
||||
PFN_vkGetInstanceProcAddr instProc;
|
||||
PFN_vkGetDeviceProcAddr devProc;
|
||||
if (!sk_gpu_test::LoadVkLibraryAndGetProcAddrFuncs(&instProc, &devProc)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto createVkSurface = [window, instProc] (VkInstance instance) -> VkSurfaceKHR {
|
||||
PFN_vkCreateAndroidSurfaceKHR createAndroidSurfaceKHR =
|
||||
(PFN_vkCreateAndroidSurfaceKHR)vkGetInstanceProcAddr(instance,
|
||||
"vkCreateAndroidSurfaceKHR");
|
||||
(PFN_vkCreateAndroidSurfaceKHR) instProc(instance, "vkCreateAndroidSurfaceKHR");
|
||||
|
||||
if (!window) {
|
||||
return VK_NULL_HANDLE;
|
||||
@ -38,7 +45,8 @@ WindowContext* NewVulkanForAndroid(ANativeWindow* window, const DisplayParams& p
|
||||
|
||||
auto canPresent = [](VkInstance, VkPhysicalDevice, uint32_t) { return true; };
|
||||
|
||||
WindowContext* ctx = new VulkanWindowContext(params, createVkSurface, canPresent);
|
||||
WindowContext* ctx = new VulkanWindowContext(params, createVkSurface, canPresent,
|
||||
instProc, devProc);
|
||||
if (!ctx->isValid()) {
|
||||
delete ctx;
|
||||
return nullptr;
|
||||
|
@ -10,6 +10,8 @@
|
||||
#include "vk/GrVkInterface.h"
|
||||
#include "vk/GrVkUtil.h"
|
||||
|
||||
#include "vk/VkTestUtils.h"
|
||||
|
||||
#include <X11/Xlib-xcb.h>
|
||||
|
||||
#include "WindowContextFactory_unix.h"
|
||||
@ -20,12 +22,17 @@ namespace sk_app {
|
||||
namespace window_context_factory {
|
||||
|
||||
WindowContext* NewVulkanForXlib(const XlibWindowInfo& info, const DisplayParams& displayParams) {
|
||||
auto createVkSurface = [&info](VkInstance instance) -> VkSurfaceKHR {
|
||||
PFN_vkGetInstanceProcAddr instProc;
|
||||
PFN_vkGetDeviceProcAddr devProc;
|
||||
if (!sk_gpu_test::LoadVkLibraryAndGetProcAddrFuncs(&instProc, &devProc)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto createVkSurface = [&info, instProc](VkInstance instance) -> VkSurfaceKHR {
|
||||
static PFN_vkCreateXcbSurfaceKHR createXcbSurfaceKHR = nullptr;
|
||||
if (!createXcbSurfaceKHR) {
|
||||
createXcbSurfaceKHR =
|
||||
(PFN_vkCreateXcbSurfaceKHR) vkGetInstanceProcAddr(instance,
|
||||
"vkCreateXcbSurfaceKHR");
|
||||
(PFN_vkCreateXcbSurfaceKHR) instProc(instance, "vkCreateXcbSurfaceKHR");
|
||||
}
|
||||
|
||||
VkSurfaceKHR surface;
|
||||
@ -46,15 +53,14 @@ WindowContext* NewVulkanForXlib(const XlibWindowInfo& info, const DisplayParams&
|
||||
return surface;
|
||||
};
|
||||
|
||||
auto canPresent = [&info](VkInstance instance, VkPhysicalDevice physDev,
|
||||
auto canPresent = [&info, instProc](VkInstance instance, VkPhysicalDevice physDev,
|
||||
uint32_t queueFamilyIndex) {
|
||||
static PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR
|
||||
getPhysicalDeviceXcbPresentationSupportKHR = nullptr;
|
||||
if (!getPhysicalDeviceXcbPresentationSupportKHR) {
|
||||
getPhysicalDeviceXcbPresentationSupportKHR =
|
||||
(PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR)
|
||||
vkGetInstanceProcAddr(instance,
|
||||
"vkGetPhysicalDeviceXcbPresentationSupportKHR");
|
||||
instProc(instance, "vkGetPhysicalDeviceXcbPresentationSupportKHR");
|
||||
}
|
||||
|
||||
|
||||
@ -66,7 +72,8 @@ WindowContext* NewVulkanForXlib(const XlibWindowInfo& info, const DisplayParams&
|
||||
visualID);
|
||||
return (VK_FALSE != check);
|
||||
};
|
||||
WindowContext* context = new VulkanWindowContext(displayParams, createVkSurface, canPresent);
|
||||
WindowContext* context = new VulkanWindowContext(displayParams, createVkSurface, canPresent,
|
||||
instProc, devProc);
|
||||
if (!context->isValid()) {
|
||||
delete context;
|
||||
return nullptr;
|
||||
|
@ -15,15 +15,23 @@
|
||||
#include "vk/GrVkInterface.h"
|
||||
#include "vk/GrVkUtil.h"
|
||||
|
||||
#include "vk/VkTestUtils.h"
|
||||
|
||||
namespace sk_app {
|
||||
namespace window_context_factory {
|
||||
|
||||
WindowContext* NewVulkanForWin(HWND hwnd, const DisplayParams& params) {
|
||||
auto createVkSurface = [hwnd] (VkInstance instance) -> VkSurfaceKHR {
|
||||
PFN_vkGetInstanceProcAddr instProc;
|
||||
PFN_vkGetDeviceProcAddr devProc;
|
||||
if (!sk_gpu_test::LoadVkLibraryAndGetProcAddrFuncs(&instProc, &devProc)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto createVkSurface = [hwnd, instProc] (VkInstance instance) -> VkSurfaceKHR {
|
||||
static PFN_vkCreateWin32SurfaceKHR createWin32SurfaceKHR = nullptr;
|
||||
if (!createWin32SurfaceKHR) {
|
||||
createWin32SurfaceKHR = (PFN_vkCreateWin32SurfaceKHR)
|
||||
vkGetInstanceProcAddr(instance, "vkCreateWin32SurfaceKHR");
|
||||
instProc(instance, "vkCreateWin32SurfaceKHR");
|
||||
}
|
||||
HINSTANCE hinstance = GetModuleHandle(0);
|
||||
VkSurfaceKHR surface;
|
||||
@ -44,22 +52,22 @@ WindowContext* NewVulkanForWin(HWND hwnd, const DisplayParams& params) {
|
||||
return surface;
|
||||
};
|
||||
|
||||
auto canPresent = [] (VkInstance instance, VkPhysicalDevice physDev,
|
||||
uint32_t queueFamilyIndex) {
|
||||
auto canPresent = [instProc] (VkInstance instance, VkPhysicalDevice physDev,
|
||||
uint32_t queueFamilyIndex) {
|
||||
static PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR
|
||||
getPhysicalDeviceWin32PresentationSupportKHR = nullptr;
|
||||
if (!getPhysicalDeviceWin32PresentationSupportKHR) {
|
||||
getPhysicalDeviceWin32PresentationSupportKHR =
|
||||
(PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR)
|
||||
vkGetInstanceProcAddr(instance,
|
||||
"vkGetPhysicalDeviceWin32PresentationSupportKHR");
|
||||
instProc(instance, "vkGetPhysicalDeviceWin32PresentationSupportKHR");
|
||||
}
|
||||
|
||||
VkBool32 check = getPhysicalDeviceWin32PresentationSupportKHR(physDev, queueFamilyIndex);
|
||||
return (VK_FALSE != check);
|
||||
};
|
||||
|
||||
WindowContext* ctx = new VulkanWindowContext(params, createVkSurface, canPresent);
|
||||
WindowContext* ctx = new VulkanWindowContext(params, createVkSurface, canPresent,
|
||||
instProc, devProc);
|
||||
if (!ctx->isValid()) {
|
||||
delete ctx;
|
||||
return nullptr;
|
||||
|
Loading…
Reference in New Issue
Block a user