Vulkan: Always request all VkSurfaceKHR-related extensions

The backend had a "requiredInstanceExtensions" parameter to device
creation so that we could request the right instance extensions to
support swapchains. When we have dawn_native::Instance we don't want to
require this information before we can use the Vulkan backend. Instead
we make the backend always require all VkSurfaceKHR extensions. This
should be safe because these extensions basically enable copying a
struct into an opaque VkSurfaceKHR object and not much else.

BUG=dawn:29

Change-Id: I7fc5426f5770b65bb35f02793a1319eb0653782c
Reviewed-on: https://dawn-review.googlesource.com/c/3662
Reviewed-by: Stephen White <senorblanco@chromium.org>
Reviewed-by: Kai Ninomiya <kainino@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
This commit is contained in:
Corentin Wallez 2019-01-07 12:04:46 +00:00 committed by Commit Bot service account
parent 95fd2821c2
commit 7c0f0fbf91
6 changed files with 67 additions and 34 deletions

View File

@ -54,8 +54,8 @@ const char kVulkanLibName[] = "vulkan-1.dll";
namespace dawn_native { namespace vulkan {
dawnDevice CreateDevice(const std::vector<const char*>& requiredInstanceExtensions) {
return reinterpret_cast<dawnDevice>(new Device(requiredInstanceExtensions));
dawnDevice CreateDevice() {
return reinterpret_cast<dawnDevice>(new Device());
}
VkInstance GetInstance(dawnDevice device) {
@ -87,8 +87,8 @@ namespace dawn_native { namespace vulkan {
// Device
Device::Device(const std::vector<const char*>& requiredInstanceExtensions) {
MaybeError maybeError = Initialize(requiredInstanceExtensions);
Device::Device() {
MaybeError maybeError = Initialize();
// In device initialization, the error callback can't have been set yet.
// So it's too early to use ConsumedError - consume the error manually.
@ -101,7 +101,7 @@ namespace dawn_native { namespace vulkan {
}
}
MaybeError Device::Initialize(const std::vector<const char*>& requiredInstanceExtensions) {
MaybeError Device::Initialize() {
if (!mVulkanLib.Open(kVulkanLibName)) {
return DAWN_CONTEXT_LOST_ERROR(std::string("Couldn't open ") + kVulkanLibName);
}
@ -112,7 +112,7 @@ namespace dawn_native { namespace vulkan {
DAWN_TRY_ASSIGN(mGlobalInfo, GatherGlobalInfo(*this));
VulkanGlobalKnobs usedGlobalKnobs = {};
DAWN_TRY_ASSIGN(usedGlobalKnobs, CreateInstance(requiredInstanceExtensions));
DAWN_TRY_ASSIGN(usedGlobalKnobs, CreateInstance());
*static_cast<VulkanGlobalKnobs*>(&mGlobalInfo) = usedGlobalKnobs;
DAWN_TRY(functions->LoadInstanceProcs(mInstance, mGlobalInfo));
@ -421,22 +421,11 @@ namespace dawn_native { namespace vulkan {
mWaitSemaphores.push_back(semaphore);
}
ResultOrError<VulkanGlobalKnobs> Device::CreateInstance(
const std::vector<const char*>& requiredExtensions) {
ResultOrError<VulkanGlobalKnobs> Device::CreateInstance() {
VulkanGlobalKnobs usedKnobs = {};
std::vector<const char*> layersToRequest;
std::vector<const char*> extensionsToRequest = requiredExtensions;
auto AddExtensionIfNotPresent = [](std::vector<const char*>* extensions,
const char* extension) {
for (const char* present : *extensions) {
if (strcmp(present, extension) == 0) {
return;
}
}
extensions->push_back(extension);
};
std::vector<const char*> extensionsToRequest;
// vktrace works by instering a layer, but we hide it behind a macro due to the vktrace
// layer crashes when used without vktrace server started, see this vktrace issue:
@ -463,14 +452,36 @@ namespace dawn_native { namespace vulkan {
usedKnobs.standardValidation = true;
}
if (mGlobalInfo.debugReport) {
AddExtensionIfNotPresent(&extensionsToRequest, kExtensionNameExtDebugReport);
extensionsToRequest.push_back(kExtensionNameExtDebugReport);
usedKnobs.debugReport = true;
}
#endif
// Always request all extensions used to create VkSurfaceKHR objects so that they are
// always available for embedders looking to create VkSurfaceKHR on our VkInstance.
if (mGlobalInfo.macosSurface) {
extensionsToRequest.push_back(kExtensionNameMvkMacosSurface);
usedKnobs.macosSurface = true;
}
if (mGlobalInfo.surface) {
AddExtensionIfNotPresent(&extensionsToRequest, kExtensionNameKhrSurface);
extensionsToRequest.push_back(kExtensionNameKhrSurface);
usedKnobs.surface = true;
}
if (mGlobalInfo.waylandSurface) {
extensionsToRequest.push_back(kExtensionNameKhrWaylandSurface);
usedKnobs.waylandSurface = true;
}
if (mGlobalInfo.win32Surface) {
extensionsToRequest.push_back(kExtensionNameKhrWin32Surface);
usedKnobs.win32Surface = true;
}
if (mGlobalInfo.xcbSurface) {
extensionsToRequest.push_back(kExtensionNameKhrXcbSurface);
usedKnobs.xcbSurface = true;
}
if (mGlobalInfo.xlibSurface) {
extensionsToRequest.push_back(kExtensionNameKhrXlibSurface);
usedKnobs.xlibSurface = true;
}
VkApplicationInfo appInfo;
appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;

View File

@ -38,7 +38,7 @@ namespace dawn_native { namespace vulkan {
class Device : public DeviceBase {
public:
Device(const std::vector<const char*>& requiredInstanceExtensions);
Device();
~Device();
// Contains all the Vulkan entry points, vkDoFoo is called via device->fn.DoFoo.
@ -96,9 +96,8 @@ namespace dawn_native { namespace vulkan {
TextureBase* texture,
const TextureViewDescriptor* descriptor) override;
MaybeError Initialize(const std::vector<const char*>& requiredInstanceExtensions);
ResultOrError<VulkanGlobalKnobs> CreateInstance(
const std::vector<const char*>& requiredExtensions);
MaybeError Initialize();
ResultOrError<VulkanGlobalKnobs> CreateInstance();
ResultOrError<VulkanDeviceKnobs> CreateDevice();
void GatherQueueFromDevice();

View File

@ -35,8 +35,13 @@ namespace dawn_native { namespace vulkan {
const char kLayerNameRenderDocCapture[] = "VK_LAYER_RENDERDOC_Capture";
const char kExtensionNameExtDebugReport[] = "VK_EXT_debug_report";
const char kExtensionNameMvkMacosSurface[] = "VK_MVK_macos_surface";
const char kExtensionNameKhrSurface[] = "VK_KHR_surface";
const char kExtensionNameKhrSwapchain[] = "VK_KHR_swapchain";
const char kExtensionNameKhrWaylandSurface[] = "VK_KHR_wayland_surface";
const char kExtensionNameKhrWin32Surface[] = "VK_KHR_win32_surface";
const char kExtensionNameKhrXcbSurface[] = "VK_KHR_xcb_surface";
const char kExtensionNameKhrXlibSurface[] = "VK_KHR_xlib_surface";
ResultOrError<VulkanGlobalInfo> GatherGlobalInfo(const Device& device) {
VulkanGlobalInfo info = {};
@ -91,9 +96,24 @@ namespace dawn_native { namespace vulkan {
if (IsExtensionName(extension, kExtensionNameExtDebugReport)) {
info.debugReport = true;
}
if (IsExtensionName(extension, kExtensionNameMvkMacosSurface)) {
info.macosSurface = true;
}
if (IsExtensionName(extension, kExtensionNameKhrSurface)) {
info.surface = true;
}
if (IsExtensionName(extension, kExtensionNameKhrWaylandSurface)) {
info.waylandSurface = true;
}
if (IsExtensionName(extension, kExtensionNameKhrWin32Surface)) {
info.win32Surface = true;
}
if (IsExtensionName(extension, kExtensionNameKhrXcbSurface)) {
info.xcbSurface = true;
}
if (IsExtensionName(extension, kExtensionNameKhrXlibSurface)) {
info.xlibSurface = true;
}
}
}

View File

@ -29,8 +29,13 @@ namespace dawn_native { namespace vulkan {
extern const char kLayerNameRenderDocCapture[];
extern const char kExtensionNameExtDebugReport[];
extern const char kExtensionNameMvkMacosSurface[];
extern const char kExtensionNameKhrSurface[];
extern const char kExtensionNameKhrSwapchain[];
extern const char kExtensionNameKhrWaylandSurface[];
extern const char kExtensionNameKhrWin32Surface[];
extern const char kExtensionNameKhrXcbSurface[];
extern const char kExtensionNameKhrXlibSurface[];
// Global information - gathered before the instance is created
struct VulkanGlobalKnobs {
@ -41,7 +46,12 @@ namespace dawn_native { namespace vulkan {
// Extensions
bool debugReport = false;
bool macosSurface = false;
bool surface = false;
bool waylandSurface = false;
bool win32Surface = false;
bool xcbSurface = false;
bool xlibSurface = false;
};
struct VulkanGlobalInfo : VulkanGlobalKnobs {

View File

@ -24,8 +24,7 @@
#include <vector>
namespace dawn_native { namespace vulkan {
DAWN_NATIVE_EXPORT dawnDevice
CreateDevice(const std::vector<const char*>& requiredInstanceExtensions);
DAWN_NATIVE_EXPORT dawnDevice CreateDevice();
DAWN_NATIVE_EXPORT VkInstance GetInstance(dawnDevice device);

View File

@ -28,13 +28,7 @@ namespace utils {
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
}
dawnDevice CreateDevice() override {
uint32_t extensionCount = 0;
const char** glfwInstanceExtensions =
glfwGetRequiredInstanceExtensions(&extensionCount);
std::vector<const char*> requiredExtensions(glfwInstanceExtensions,
glfwInstanceExtensions + extensionCount);
mDevice = dawn_native::vulkan::CreateDevice(requiredExtensions);
mDevice = dawn_native::vulkan::CreateDevice();
return mDevice;
}
uint64_t GetSwapChainImplementation() override {