mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-07-12 08:05:53 +00:00
Vulkan: Implement the backend connection and adapter.
This also changes VulkanInfo to gather info on backends / adapters instead of the device, because all the info gathering can happen before the device is created. BUG=dawn:29 Change-Id: I9dc4412f494428f1ae589544d3adf76fe8b9a3a3 Reviewed-on: https://dawn-review.googlesource.com/c/3941 Commit-Queue: Corentin Wallez <cwallez@chromium.org> Reviewed-by: Kai Ninomiya <kainino@chromium.org>
This commit is contained in:
parent
c26f6dae33
commit
d1be0e7077
4
BUILD.gn
4
BUILD.gn
@ -649,6 +649,10 @@ source_set("libdawn_native_sources") {
|
||||
if (dawn_enable_vulkan) {
|
||||
deps += [ "third_party:vulkan_headers" ]
|
||||
sources += [
|
||||
"src/dawn_native/vulkan/AdapterVk.cpp",
|
||||
"src/dawn_native/vulkan/AdapterVk.h",
|
||||
"src/dawn_native/vulkan/BackendVk.cpp",
|
||||
"src/dawn_native/vulkan/BackendVk.h",
|
||||
"src/dawn_native/vulkan/BindGroupLayoutVk.cpp",
|
||||
"src/dawn_native/vulkan/BindGroupLayoutVk.h",
|
||||
"src/dawn_native/vulkan/BindGroupVk.cpp",
|
||||
|
56
src/dawn_native/vulkan/AdapterVk.cpp
Normal file
56
src/dawn_native/vulkan/AdapterVk.cpp
Normal file
@ -0,0 +1,56 @@
|
||||
// Copyright 2019 The Dawn Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "dawn_native/vulkan/AdapterVk.h"
|
||||
|
||||
#include "dawn_native/vulkan/BackendVk.h"
|
||||
#include "dawn_native/vulkan/DeviceVk.h"
|
||||
|
||||
namespace dawn_native { namespace vulkan {
|
||||
|
||||
Adapter::Adapter(Backend* backend, VkPhysicalDevice physicalDevice)
|
||||
: AdapterBase(backend->GetInstance(), BackendType::Vulkan),
|
||||
mPhysicalDevice(physicalDevice),
|
||||
mBackend(backend) {
|
||||
}
|
||||
|
||||
const VulkanDeviceInfo& Adapter::GetDeviceInfo() const {
|
||||
return mDeviceInfo;
|
||||
}
|
||||
|
||||
VkPhysicalDevice Adapter::GetPhysicalDevice() const {
|
||||
return mPhysicalDevice;
|
||||
}
|
||||
|
||||
Backend* Adapter::GetBackend() const {
|
||||
return mBackend;
|
||||
}
|
||||
|
||||
MaybeError Adapter::Initialize() {
|
||||
DAWN_TRY_ASSIGN(mDeviceInfo, GatherDeviceInfo(*this));
|
||||
|
||||
mPCIInfo.deviceId = mDeviceInfo.properties.deviceID;
|
||||
mPCIInfo.vendorId = mDeviceInfo.properties.vendorID;
|
||||
mPCIInfo.name = mDeviceInfo.properties.deviceName;
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
ResultOrError<DeviceBase*> Adapter::CreateDeviceImpl() {
|
||||
std::unique_ptr<Device> device = std::make_unique<Device>(this);
|
||||
DAWN_TRY(device->Initialize());
|
||||
return device.release();
|
||||
}
|
||||
|
||||
}} // namespace dawn_native::vulkan
|
48
src/dawn_native/vulkan/AdapterVk.h
Normal file
48
src/dawn_native/vulkan/AdapterVk.h
Normal file
@ -0,0 +1,48 @@
|
||||
// Copyright 2019 The Dawn Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef DAWNNATIVE_VULKAN_ADAPTERVK_H_
|
||||
#define DAWNNATIVE_VULKAN_ADAPTERVK_H_
|
||||
|
||||
#include "dawn_native/Adapter.h"
|
||||
|
||||
#include "common/vulkan_platform.h"
|
||||
#include "dawn_native/vulkan/VulkanInfo.h"
|
||||
|
||||
namespace dawn_native { namespace vulkan {
|
||||
|
||||
class Backend;
|
||||
|
||||
class Adapter : public AdapterBase {
|
||||
public:
|
||||
Adapter(Backend* backend, VkPhysicalDevice physicalDevice);
|
||||
virtual ~Adapter() = default;
|
||||
|
||||
const VulkanDeviceInfo& GetDeviceInfo() const;
|
||||
VkPhysicalDevice GetPhysicalDevice() const;
|
||||
Backend* GetBackend() const;
|
||||
|
||||
MaybeError Initialize();
|
||||
|
||||
private:
|
||||
ResultOrError<DeviceBase*> CreateDeviceImpl() override;
|
||||
|
||||
VkPhysicalDevice mPhysicalDevice;
|
||||
Backend* mBackend;
|
||||
VulkanDeviceInfo mDeviceInfo = {};
|
||||
};
|
||||
|
||||
}} // namespace dawn_native::vulkan
|
||||
|
||||
#endif // DAWNNATIVE_VULKAN_ADAPTERVK_H_
|
224
src/dawn_native/vulkan/BackendVk.cpp
Normal file
224
src/dawn_native/vulkan/BackendVk.cpp
Normal file
@ -0,0 +1,224 @@
|
||||
// Copyright 2019 The Dawn Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "dawn_native/vulkan/BackendVk.h"
|
||||
|
||||
#include "dawn_native/Instance.h"
|
||||
#include "dawn_native/VulkanBackend.h"
|
||||
#include "dawn_native/vulkan/AdapterVk.h"
|
||||
#include "dawn_native/vulkan/VulkanError.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#if DAWN_PLATFORM_LINUX
|
||||
const char kVulkanLibName[] = "libvulkan.so.1";
|
||||
#elif DAWN_PLATFORM_WINDOWS
|
||||
const char kVulkanLibName[] = "vulkan-1.dll";
|
||||
#else
|
||||
# error "Unimplemented Vulkan backend platform"
|
||||
#endif
|
||||
|
||||
namespace dawn_native { namespace vulkan {
|
||||
|
||||
Backend::Backend(InstanceBase* instance) : BackendConnection(instance, BackendType::Vulkan) {
|
||||
}
|
||||
|
||||
Backend::~Backend() {
|
||||
if (mDebugReportCallback != VK_NULL_HANDLE) {
|
||||
mFunctions.DestroyDebugReportCallbackEXT(mInstance, mDebugReportCallback, nullptr);
|
||||
mDebugReportCallback = VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
// VkPhysicalDevices are destroyed when the VkInstance is destroyed
|
||||
if (mInstance != VK_NULL_HANDLE) {
|
||||
mFunctions.DestroyInstance(mInstance, nullptr);
|
||||
mInstance = VK_NULL_HANDLE;
|
||||
}
|
||||
}
|
||||
|
||||
const VulkanFunctions& Backend::GetFunctions() const {
|
||||
return mFunctions;
|
||||
}
|
||||
|
||||
VkInstance Backend::GetVkInstance() const {
|
||||
return mInstance;
|
||||
}
|
||||
|
||||
MaybeError Backend::Initialize() {
|
||||
if (!mVulkanLib.Open(kVulkanLibName)) {
|
||||
return DAWN_CONTEXT_LOST_ERROR(std::string("Couldn't open ") + kVulkanLibName);
|
||||
}
|
||||
|
||||
DAWN_TRY(mFunctions.LoadGlobalProcs(mVulkanLib));
|
||||
|
||||
DAWN_TRY_ASSIGN(mGlobalInfo, GatherGlobalInfo(*this));
|
||||
|
||||
VulkanGlobalKnobs usedGlobalKnobs = {};
|
||||
DAWN_TRY_ASSIGN(usedGlobalKnobs, CreateInstance());
|
||||
*static_cast<VulkanGlobalKnobs*>(&mGlobalInfo) = usedGlobalKnobs;
|
||||
|
||||
DAWN_TRY(mFunctions.LoadInstanceProcs(mInstance, mGlobalInfo));
|
||||
|
||||
if (usedGlobalKnobs.debugReport) {
|
||||
DAWN_TRY(RegisterDebugReport());
|
||||
}
|
||||
|
||||
DAWN_TRY_ASSIGN(mPhysicalDevices, GetPhysicalDevices(*this));
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
std::vector<std::unique_ptr<AdapterBase>> Backend::DiscoverDefaultAdapters() {
|
||||
std::vector<std::unique_ptr<AdapterBase>> adapters;
|
||||
|
||||
for (VkPhysicalDevice physicalDevice : mPhysicalDevices) {
|
||||
std::unique_ptr<Adapter> adapter = std::make_unique<Adapter>(this, physicalDevice);
|
||||
|
||||
if (GetInstance()->ConsumedError(adapter->Initialize())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
adapters.push_back(std::move(adapter));
|
||||
}
|
||||
|
||||
return adapters;
|
||||
}
|
||||
|
||||
ResultOrError<VulkanGlobalKnobs> Backend::CreateInstance() {
|
||||
VulkanGlobalKnobs usedKnobs = {};
|
||||
|
||||
std::vector<const char*> layersToRequest;
|
||||
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:
|
||||
// https://github.com/LunarG/VulkanTools/issues/254
|
||||
// Also it is good to put it in first position so that it doesn't see Vulkan calls inserted
|
||||
// by other layers.
|
||||
#if defined(DAWN_USE_VKTRACE)
|
||||
if (mGlobalInfo.vktrace) {
|
||||
layersToRequest.push_back(kLayerNameLunargVKTrace);
|
||||
usedKnobs.vktrace = true;
|
||||
}
|
||||
#endif
|
||||
// RenderDoc installs a layer at the system level for its capture but we don't want to use
|
||||
// it unless we are debugging in RenderDoc so we hide it behind a macro.
|
||||
#if defined(DAWN_USE_RENDERDOC)
|
||||
if (mGlobalInfo.renderDocCapture) {
|
||||
layersToRequest.push_back(kLayerNameRenderDocCapture);
|
||||
usedKnobs.renderDocCapture = true;
|
||||
}
|
||||
#endif
|
||||
#if defined(DAWN_ENABLE_ASSERTS)
|
||||
if (mGlobalInfo.standardValidation) {
|
||||
layersToRequest.push_back(kLayerNameLunargStandardValidation);
|
||||
usedKnobs.standardValidation = true;
|
||||
}
|
||||
if (mGlobalInfo.debugReport) {
|
||||
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) {
|
||||
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;
|
||||
appInfo.pNext = nullptr;
|
||||
appInfo.pApplicationName = nullptr;
|
||||
appInfo.applicationVersion = 0;
|
||||
appInfo.pEngineName = nullptr;
|
||||
appInfo.engineVersion = 0;
|
||||
appInfo.apiVersion = VK_API_VERSION_1_0;
|
||||
|
||||
VkInstanceCreateInfo createInfo;
|
||||
createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
|
||||
createInfo.pNext = nullptr;
|
||||
createInfo.flags = 0;
|
||||
createInfo.pApplicationInfo = &appInfo;
|
||||
createInfo.enabledLayerCount = static_cast<uint32_t>(layersToRequest.size());
|
||||
createInfo.ppEnabledLayerNames = layersToRequest.data();
|
||||
createInfo.enabledExtensionCount = static_cast<uint32_t>(extensionsToRequest.size());
|
||||
createInfo.ppEnabledExtensionNames = extensionsToRequest.data();
|
||||
|
||||
DAWN_TRY(CheckVkSuccess(mFunctions.CreateInstance(&createInfo, nullptr, &mInstance),
|
||||
"vkCreateInstance"));
|
||||
|
||||
return usedKnobs;
|
||||
}
|
||||
|
||||
MaybeError Backend::RegisterDebugReport() {
|
||||
VkDebugReportCallbackCreateInfoEXT createInfo;
|
||||
createInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT;
|
||||
createInfo.pNext = nullptr;
|
||||
createInfo.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT;
|
||||
createInfo.pfnCallback = Backend::OnDebugReportCallback;
|
||||
createInfo.pUserData = this;
|
||||
|
||||
return CheckVkSuccess(mFunctions.CreateDebugReportCallbackEXT(
|
||||
mInstance, &createInfo, nullptr, &mDebugReportCallback),
|
||||
"vkCreateDebugReportcallback");
|
||||
}
|
||||
|
||||
VKAPI_ATTR VkBool32 VKAPI_CALL
|
||||
Backend::OnDebugReportCallback(VkDebugReportFlagsEXT flags,
|
||||
VkDebugReportObjectTypeEXT /*objectType*/,
|
||||
uint64_t /*object*/,
|
||||
size_t /*location*/,
|
||||
int32_t /*messageCode*/,
|
||||
const char* /*pLayerPrefix*/,
|
||||
const char* pMessage,
|
||||
void* /*pUserdata*/) {
|
||||
std::cout << pMessage << std::endl;
|
||||
ASSERT((flags & VK_DEBUG_REPORT_ERROR_BIT_EXT) == 0);
|
||||
|
||||
return VK_FALSE;
|
||||
}
|
||||
|
||||
BackendConnection* Connect(InstanceBase* instance) {
|
||||
Backend* backend = new Backend(instance);
|
||||
|
||||
if (instance->ConsumedError(backend->Initialize())) {
|
||||
delete backend;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return backend;
|
||||
}
|
||||
|
||||
}} // namespace dawn_native::vulkan
|
64
src/dawn_native/vulkan/BackendVk.h
Normal file
64
src/dawn_native/vulkan/BackendVk.h
Normal file
@ -0,0 +1,64 @@
|
||||
// Copyright 2019 The Dawn Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef DAWNNATIVE_VULKAN_BACKENDVK_H_
|
||||
#define DAWNNATIVE_VULKAN_BACKENDVK_H_
|
||||
|
||||
#include "dawn_native/BackendConnection.h"
|
||||
|
||||
#include "common/DynamicLib.h"
|
||||
#include "dawn_native/vulkan/VulkanFunctions.h"
|
||||
#include "dawn_native/vulkan/VulkanInfo.h"
|
||||
|
||||
namespace dawn_native { namespace vulkan {
|
||||
|
||||
class Backend : public BackendConnection {
|
||||
public:
|
||||
Backend(InstanceBase* instance);
|
||||
~Backend() override;
|
||||
|
||||
const VulkanFunctions& GetFunctions() const;
|
||||
VkInstance GetVkInstance() const;
|
||||
|
||||
MaybeError Initialize();
|
||||
|
||||
std::vector<std::unique_ptr<AdapterBase>> DiscoverDefaultAdapters() override;
|
||||
|
||||
private:
|
||||
ResultOrError<VulkanGlobalKnobs> CreateInstance();
|
||||
|
||||
MaybeError RegisterDebugReport();
|
||||
static VKAPI_ATTR VkBool32 VKAPI_CALL
|
||||
OnDebugReportCallback(VkDebugReportFlagsEXT flags,
|
||||
VkDebugReportObjectTypeEXT objectType,
|
||||
uint64_t object,
|
||||
size_t location,
|
||||
int32_t messageCode,
|
||||
const char* pLayerPrefix,
|
||||
const char* pMessage,
|
||||
void* pUserdata);
|
||||
|
||||
DynamicLib mVulkanLib;
|
||||
VulkanGlobalInfo mGlobalInfo = {};
|
||||
VkInstance mInstance = VK_NULL_HANDLE;
|
||||
VulkanFunctions mFunctions;
|
||||
|
||||
VkDebugReportCallbackEXT mDebugReportCallback = VK_NULL_HANDLE;
|
||||
|
||||
std::vector<VkPhysicalDevice> mPhysicalDevices;
|
||||
};
|
||||
|
||||
}} // namespace dawn_native::vulkan
|
||||
|
||||
#endif // DAWNNATIVE_VULKAN_BACKENDVK_H_
|
@ -19,6 +19,8 @@
|
||||
#include "dawn_native/Commands.h"
|
||||
#include "dawn_native/DynamicUploader.h"
|
||||
#include "dawn_native/ErrorData.h"
|
||||
#include "dawn_native/vulkan/AdapterVk.h"
|
||||
#include "dawn_native/vulkan/BackendVk.h"
|
||||
#include "dawn_native/vulkan/BindGroupLayoutVk.h"
|
||||
#include "dawn_native/vulkan/BindGroupVk.h"
|
||||
#include "dawn_native/vulkan/BufferUploader.h"
|
||||
@ -38,72 +40,22 @@
|
||||
#include "dawn_native/vulkan/TextureVk.h"
|
||||
#include "dawn_native/vulkan/VulkanError.h"
|
||||
|
||||
#include <spirv-cross/spirv_cross.hpp>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#if DAWN_PLATFORM_LINUX
|
||||
const char kVulkanLibName[] = "libvulkan.so.1";
|
||||
#elif DAWN_PLATFORM_WINDOWS
|
||||
const char kVulkanLibName[] = "vulkan-1.dll";
|
||||
#else
|
||||
# error "Unimplemented Vulkan backend platform"
|
||||
#endif
|
||||
|
||||
namespace dawn_native { namespace vulkan {
|
||||
|
||||
BackendConnection* Connect(InstanceBase* instance) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Device
|
||||
|
||||
Device::Device() : DeviceBase(nullptr) {
|
||||
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.
|
||||
if (DAWN_UNLIKELY(maybeError.IsError())) {
|
||||
ErrorData* error = maybeError.AcquireError();
|
||||
printf("Device initialization error: %s\n", error->GetMessage().c_str());
|
||||
delete error;
|
||||
ASSERT(false);
|
||||
return;
|
||||
}
|
||||
Device::Device(Adapter* adapter) : DeviceBase(adapter) {
|
||||
}
|
||||
|
||||
MaybeError Device::Initialize() {
|
||||
if (!mVulkanLib.Open(kVulkanLibName)) {
|
||||
return DAWN_CONTEXT_LOST_ERROR(std::string("Couldn't open ") + kVulkanLibName);
|
||||
}
|
||||
// Copy the adapter's device info to the device so that we can change the "knobs"
|
||||
mDeviceInfo = ToBackend(GetAdapter())->GetDeviceInfo();
|
||||
|
||||
VulkanFunctions* functions = GetMutableFunctions();
|
||||
DAWN_TRY(functions->LoadGlobalProcs(mVulkanLib));
|
||||
*functions = ToBackend(GetAdapter())->GetBackend()->GetFunctions();
|
||||
|
||||
DAWN_TRY_ASSIGN(mGlobalInfo, GatherGlobalInfo(*this));
|
||||
|
||||
VulkanGlobalKnobs usedGlobalKnobs = {};
|
||||
DAWN_TRY_ASSIGN(usedGlobalKnobs, CreateInstance());
|
||||
*static_cast<VulkanGlobalKnobs*>(&mGlobalInfo) = usedGlobalKnobs;
|
||||
|
||||
DAWN_TRY(functions->LoadInstanceProcs(mInstance, mGlobalInfo));
|
||||
|
||||
if (usedGlobalKnobs.debugReport) {
|
||||
DAWN_TRY(RegisterDebugReport());
|
||||
}
|
||||
|
||||
std::vector<VkPhysicalDevice> physicalDevices;
|
||||
DAWN_TRY_ASSIGN(physicalDevices, GetPhysicalDevices(*this));
|
||||
if (physicalDevices.empty()) {
|
||||
return DAWN_CONTEXT_LOST_ERROR("No physical devices");
|
||||
}
|
||||
// TODO(cwallez@chromium.org): Choose the physical device based on ???
|
||||
mPhysicalDevice = physicalDevices[0];
|
||||
|
||||
DAWN_TRY_ASSIGN(mDeviceInfo, GatherDeviceInfo(*this, mPhysicalDevice));
|
||||
VkPhysicalDevice physicalDevice = ToBackend(GetAdapter())->GetPhysicalDevice();
|
||||
|
||||
VulkanDeviceKnobs usedDeviceKnobs = {};
|
||||
DAWN_TRY_ASSIGN(usedDeviceKnobs, CreateDevice());
|
||||
DAWN_TRY_ASSIGN(usedDeviceKnobs, CreateDevice(physicalDevice));
|
||||
*static_cast<VulkanDeviceKnobs*>(&mDeviceInfo) = usedDeviceKnobs;
|
||||
|
||||
DAWN_TRY(functions->LoadDeviceProcs(mVkDevice, mDeviceInfo));
|
||||
@ -116,10 +68,6 @@ namespace dawn_native { namespace vulkan {
|
||||
mMemoryAllocator = std::make_unique<MemoryAllocator>(this);
|
||||
mRenderPassCache = std::make_unique<RenderPassCache>(this);
|
||||
|
||||
mPCIInfo.deviceId = mDeviceInfo.properties.deviceID;
|
||||
mPCIInfo.vendorId = mDeviceInfo.properties.vendorID;
|
||||
mPCIInfo.name = mDeviceInfo.properties.deviceName;
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
@ -182,17 +130,6 @@ namespace dawn_native { namespace vulkan {
|
||||
fn.DestroyDevice(mVkDevice, nullptr);
|
||||
mVkDevice = VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
if (mDebugReportCallback != VK_NULL_HANDLE) {
|
||||
fn.DestroyDebugReportCallbackEXT(mInstance, mDebugReportCallback, nullptr);
|
||||
mDebugReportCallback = VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
// VkPhysicalDevices are destroyed when the VkInstance is destroyed
|
||||
if (mInstance != VK_NULL_HANDLE) {
|
||||
fn.DestroyInstance(mInstance, nullptr);
|
||||
mInstance = VK_NULL_HANDLE;
|
||||
}
|
||||
}
|
||||
|
||||
ResultOrError<BindGroupBase*> Device::CreateBindGroupImpl(
|
||||
@ -283,22 +220,13 @@ namespace dawn_native { namespace vulkan {
|
||||
}
|
||||
}
|
||||
|
||||
const dawn_native::PCIInfo& Device::GetPCIInfo() const {
|
||||
return mPCIInfo;
|
||||
VkInstance Device::GetVkInstance() const {
|
||||
return ToBackend(GetAdapter())->GetBackend()->GetVkInstance();
|
||||
}
|
||||
|
||||
const VulkanDeviceInfo& Device::GetDeviceInfo() const {
|
||||
return mDeviceInfo;
|
||||
}
|
||||
|
||||
VkInstance Device::GetInstance() const {
|
||||
return mInstance;
|
||||
}
|
||||
|
||||
VkPhysicalDevice Device::GetPhysicalDevice() const {
|
||||
return mPhysicalDevice;
|
||||
}
|
||||
|
||||
VkDevice Device::GetVkDevice() const {
|
||||
return mVkDevice;
|
||||
}
|
||||
@ -392,94 +320,7 @@ namespace dawn_native { namespace vulkan {
|
||||
mWaitSemaphores.push_back(semaphore);
|
||||
}
|
||||
|
||||
ResultOrError<VulkanGlobalKnobs> Device::CreateInstance() {
|
||||
VulkanGlobalKnobs usedKnobs = {};
|
||||
|
||||
std::vector<const char*> layersToRequest;
|
||||
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:
|
||||
// https://github.com/LunarG/VulkanTools/issues/254
|
||||
// Also it is good to put it in first position so that it doesn't see Vulkan calls inserted
|
||||
// by other layers.
|
||||
#if defined(DAWN_USE_VKTRACE)
|
||||
if (mGlobalInfo.vktrace) {
|
||||
layersToRequest.push_back(kLayerNameLunargVKTrace);
|
||||
usedKnobs.vktrace = true;
|
||||
}
|
||||
#endif
|
||||
// RenderDoc installs a layer at the system level for its capture but we don't want to use
|
||||
// it unless we are debugging in RenderDoc so we hide it behind a macro.
|
||||
#if defined(DAWN_USE_RENDERDOC)
|
||||
if (mGlobalInfo.renderDocCapture) {
|
||||
layersToRequest.push_back(kLayerNameRenderDocCapture);
|
||||
usedKnobs.renderDocCapture = true;
|
||||
}
|
||||
#endif
|
||||
#if defined(DAWN_ENABLE_ASSERTS)
|
||||
if (mGlobalInfo.standardValidation) {
|
||||
layersToRequest.push_back(kLayerNameLunargStandardValidation);
|
||||
usedKnobs.standardValidation = true;
|
||||
}
|
||||
if (mGlobalInfo.debugReport) {
|
||||
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) {
|
||||
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;
|
||||
appInfo.pNext = nullptr;
|
||||
appInfo.pApplicationName = nullptr;
|
||||
appInfo.applicationVersion = 0;
|
||||
appInfo.pEngineName = nullptr;
|
||||
appInfo.engineVersion = 0;
|
||||
appInfo.apiVersion = VK_API_VERSION_1_0;
|
||||
|
||||
VkInstanceCreateInfo createInfo;
|
||||
createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
|
||||
createInfo.pNext = nullptr;
|
||||
createInfo.flags = 0;
|
||||
createInfo.pApplicationInfo = &appInfo;
|
||||
createInfo.enabledLayerCount = static_cast<uint32_t>(layersToRequest.size());
|
||||
createInfo.ppEnabledLayerNames = layersToRequest.data();
|
||||
createInfo.enabledExtensionCount = static_cast<uint32_t>(extensionsToRequest.size());
|
||||
createInfo.ppEnabledExtensionNames = extensionsToRequest.data();
|
||||
|
||||
DAWN_TRY(CheckVkSuccess(fn.CreateInstance(&createInfo, nullptr, &mInstance),
|
||||
"vkCreateInstance"));
|
||||
|
||||
return usedKnobs;
|
||||
}
|
||||
|
||||
ResultOrError<VulkanDeviceKnobs> Device::CreateDevice() {
|
||||
ResultOrError<VulkanDeviceKnobs> Device::CreateDevice(VkPhysicalDevice physicalDevice) {
|
||||
VulkanDeviceKnobs usedKnobs = {};
|
||||
|
||||
float zero = 0.0f;
|
||||
@ -541,7 +382,7 @@ namespace dawn_native { namespace vulkan {
|
||||
createInfo.ppEnabledExtensionNames = extensionsToRequest.data();
|
||||
createInfo.pEnabledFeatures = &usedKnobs.features;
|
||||
|
||||
DAWN_TRY(CheckVkSuccess(fn.CreateDevice(mPhysicalDevice, &createInfo, nullptr, &mVkDevice),
|
||||
DAWN_TRY(CheckVkSuccess(fn.CreateDevice(physicalDevice, &createInfo, nullptr, &mVkDevice),
|
||||
"vkCreateDevice"));
|
||||
|
||||
return usedKnobs;
|
||||
@ -551,34 +392,6 @@ namespace dawn_native { namespace vulkan {
|
||||
fn.GetDeviceQueue(mVkDevice, mQueueFamily, 0, &mQueue);
|
||||
}
|
||||
|
||||
MaybeError Device::RegisterDebugReport() {
|
||||
VkDebugReportCallbackCreateInfoEXT createInfo;
|
||||
createInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT;
|
||||
createInfo.pNext = nullptr;
|
||||
createInfo.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT;
|
||||
createInfo.pfnCallback = Device::OnDebugReportCallback;
|
||||
createInfo.pUserData = this;
|
||||
|
||||
return CheckVkSuccess(
|
||||
fn.CreateDebugReportCallbackEXT(mInstance, &createInfo, nullptr, &mDebugReportCallback),
|
||||
"vkCreateDebugReportcallback");
|
||||
}
|
||||
|
||||
VKAPI_ATTR VkBool32 VKAPI_CALL
|
||||
Device::OnDebugReportCallback(VkDebugReportFlagsEXT flags,
|
||||
VkDebugReportObjectTypeEXT /*objectType*/,
|
||||
uint64_t /*object*/,
|
||||
size_t /*location*/,
|
||||
int32_t /*messageCode*/,
|
||||
const char* /*pLayerPrefix*/,
|
||||
const char* pMessage,
|
||||
void* /*pUserdata*/) {
|
||||
std::cout << pMessage << std::endl;
|
||||
ASSERT((flags & VK_DEBUG_REPORT_ERROR_BIT_EXT) == 0);
|
||||
|
||||
return VK_FALSE;
|
||||
}
|
||||
|
||||
VulkanFunctions* Device::GetMutableFunctions() {
|
||||
return const_cast<VulkanFunctions*>(&fn);
|
||||
}
|
||||
|
@ -17,7 +17,6 @@
|
||||
|
||||
#include "dawn_native/dawn_platform.h"
|
||||
|
||||
#include "common/DynamicLib.h"
|
||||
#include "common/Serial.h"
|
||||
#include "common/SerialQueue.h"
|
||||
#include "dawn_native/Device.h"
|
||||
@ -30,6 +29,7 @@
|
||||
|
||||
namespace dawn_native { namespace vulkan {
|
||||
|
||||
class Adapter;
|
||||
class BufferUploader;
|
||||
class FencedDeleter;
|
||||
class MapRequestTracker;
|
||||
@ -38,15 +38,16 @@ namespace dawn_native { namespace vulkan {
|
||||
|
||||
class Device : public DeviceBase {
|
||||
public:
|
||||
Device();
|
||||
Device(Adapter* adapter);
|
||||
~Device();
|
||||
|
||||
MaybeError Initialize();
|
||||
|
||||
// Contains all the Vulkan entry points, vkDoFoo is called via device->fn.DoFoo.
|
||||
const VulkanFunctions fn;
|
||||
|
||||
VkInstance GetVkInstance() const;
|
||||
const VulkanDeviceInfo& GetDeviceInfo() const;
|
||||
VkInstance GetInstance() const;
|
||||
VkPhysicalDevice GetPhysicalDevice() const;
|
||||
VkDevice GetVkDevice() const;
|
||||
uint32_t GetGraphicsQueueFamily() const;
|
||||
VkQueue GetQueue() const;
|
||||
@ -73,8 +74,6 @@ namespace dawn_native { namespace vulkan {
|
||||
Serial GetLastSubmittedCommandSerial() const final override;
|
||||
void TickImpl() override;
|
||||
|
||||
const dawn_native::PCIInfo& GetPCIInfo() const override;
|
||||
|
||||
ResultOrError<std::unique_ptr<StagingBufferBase>> CreateStagingBuffer(size_t size) override;
|
||||
MaybeError CopyFromStagingToBuffer(StagingBufferBase* source,
|
||||
uint32_t sourceOffset,
|
||||
@ -103,37 +102,17 @@ namespace dawn_native { namespace vulkan {
|
||||
TextureBase* texture,
|
||||
const TextureViewDescriptor* descriptor) override;
|
||||
|
||||
MaybeError Initialize();
|
||||
ResultOrError<VulkanGlobalKnobs> CreateInstance();
|
||||
ResultOrError<VulkanDeviceKnobs> CreateDevice();
|
||||
ResultOrError<VulkanDeviceKnobs> CreateDevice(VkPhysicalDevice physicalDevice);
|
||||
void GatherQueueFromDevice();
|
||||
|
||||
MaybeError RegisterDebugReport();
|
||||
static VKAPI_ATTR VkBool32 VKAPI_CALL
|
||||
OnDebugReportCallback(VkDebugReportFlagsEXT flags,
|
||||
VkDebugReportObjectTypeEXT objectType,
|
||||
uint64_t object,
|
||||
size_t location,
|
||||
int32_t messageCode,
|
||||
const char* pLayerPrefix,
|
||||
const char* pMessage,
|
||||
void* pUserdata);
|
||||
|
||||
// To make it easier to use fn it is a public const member. However
|
||||
// the Device is allowed to mutate them through these private methods.
|
||||
VulkanFunctions* GetMutableFunctions();
|
||||
|
||||
VulkanGlobalInfo mGlobalInfo = {};
|
||||
VulkanDeviceInfo mDeviceInfo = {};
|
||||
|
||||
DynamicLib mVulkanLib;
|
||||
|
||||
VkInstance mInstance = VK_NULL_HANDLE;
|
||||
VkPhysicalDevice mPhysicalDevice = VK_NULL_HANDLE;
|
||||
VkDevice mVkDevice = VK_NULL_HANDLE;
|
||||
uint32_t mQueueFamily = 0;
|
||||
VkQueue mQueue = VK_NULL_HANDLE;
|
||||
VkDebugReportCallbackEXT mDebugReportCallback = VK_NULL_HANDLE;
|
||||
|
||||
std::unique_ptr<BufferUploader> mBufferUploader;
|
||||
std::unique_ptr<FencedDeleter> mDeleter;
|
||||
@ -166,8 +145,6 @@ namespace dawn_native { namespace vulkan {
|
||||
std::vector<CommandPoolAndBuffer> mUnusedCommands;
|
||||
CommandPoolAndBuffer mPendingCommands;
|
||||
std::vector<VkSemaphore> mWaitSemaphores;
|
||||
|
||||
dawn_native::PCIInfo mPCIInfo;
|
||||
};
|
||||
|
||||
}} // namespace dawn_native::vulkan
|
||||
|
@ -96,7 +96,7 @@ namespace dawn_native { namespace vulkan {
|
||||
|
||||
void FencedDeleter::Tick(Serial completedSerial) {
|
||||
VkDevice vkDevice = mDevice->GetVkDevice();
|
||||
VkInstance instance = mDevice->GetInstance();
|
||||
VkInstance instance = mDevice->GetVkInstance();
|
||||
|
||||
// Buffers and images must be deleted before memories because it is invalid to free memory
|
||||
// that still have resources bound to it.
|
||||
|
@ -58,7 +58,8 @@ namespace dawn_native { namespace vulkan {
|
||||
}
|
||||
|
||||
void NativeSwapChainImpl::Init(dawnWSIContextVulkan* /*context*/) {
|
||||
if (mDevice->ConsumedError(GatherSurfaceInfo(*mDevice, mSurface, &mInfo))) {
|
||||
if (mDevice->ConsumedError(
|
||||
GatherSurfaceInfo(*ToBackend(mDevice->GetAdapter()), mSurface, &mInfo))) {
|
||||
ASSERT(false);
|
||||
}
|
||||
|
||||
|
@ -27,15 +27,13 @@
|
||||
|
||||
namespace dawn_native { namespace vulkan {
|
||||
|
||||
dawnDevice CreateDevice() {
|
||||
return reinterpret_cast<dawnDevice>(new Device());
|
||||
}
|
||||
|
||||
VkInstance GetInstance(dawnDevice device) {
|
||||
Device* backendDevice = reinterpret_cast<Device*>(device);
|
||||
return backendDevice->GetInstance();
|
||||
return backendDevice->GetVkInstance();
|
||||
}
|
||||
|
||||
// Explicitly export this function because it uses the "native" type for surfaces while the
|
||||
// header as seen in this file uses the wrapped type.
|
||||
DAWN_NATIVE_EXPORT dawnSwapChainImplementation
|
||||
CreateNativeSwapChainImpl(dawnDevice device, VkSurfaceKHRNative surfaceNative) {
|
||||
Device* backendDevice = reinterpret_cast<Device*>(device);
|
||||
|
@ -14,7 +14,8 @@
|
||||
|
||||
#include "dawn_native/vulkan/VulkanInfo.h"
|
||||
|
||||
#include "dawn_native/vulkan/DeviceVk.h"
|
||||
#include "dawn_native/vulkan/AdapterVk.h"
|
||||
#include "dawn_native/vulkan/BackendVk.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
@ -43,13 +44,14 @@ namespace dawn_native { namespace vulkan {
|
||||
const char kExtensionNameKhrXcbSurface[] = "VK_KHR_xcb_surface";
|
||||
const char kExtensionNameKhrXlibSurface[] = "VK_KHR_xlib_surface";
|
||||
|
||||
ResultOrError<VulkanGlobalInfo> GatherGlobalInfo(const Device& device) {
|
||||
ResultOrError<VulkanGlobalInfo> GatherGlobalInfo(const Backend& backend) {
|
||||
VulkanGlobalInfo info = {};
|
||||
const VulkanFunctions& vkFunctions = backend.GetFunctions();
|
||||
|
||||
// Gather the info about the instance layers
|
||||
{
|
||||
uint32_t count = 0;
|
||||
VkResult result = device.fn.EnumerateInstanceLayerProperties(&count, nullptr);
|
||||
VkResult result = vkFunctions.EnumerateInstanceLayerProperties(&count, nullptr);
|
||||
// From the Vulkan spec result should be success if there are 0 layers,
|
||||
// incomplete otherwise. This means that both values represent a success.
|
||||
// This is the same for all Enumarte functions
|
||||
@ -58,7 +60,7 @@ namespace dawn_native { namespace vulkan {
|
||||
}
|
||||
|
||||
info.layers.resize(count);
|
||||
result = device.fn.EnumerateInstanceLayerProperties(&count, info.layers.data());
|
||||
result = vkFunctions.EnumerateInstanceLayerProperties(&count, info.layers.data());
|
||||
if (result != VK_SUCCESS) {
|
||||
return DAWN_CONTEXT_LOST_ERROR("vkEnumerateInstanceLayerProperties");
|
||||
}
|
||||
@ -80,14 +82,14 @@ namespace dawn_native { namespace vulkan {
|
||||
{
|
||||
uint32_t count = 0;
|
||||
VkResult result =
|
||||
device.fn.EnumerateInstanceExtensionProperties(nullptr, &count, nullptr);
|
||||
vkFunctions.EnumerateInstanceExtensionProperties(nullptr, &count, nullptr);
|
||||
if (result != VK_SUCCESS && result != VK_INCOMPLETE) {
|
||||
return DAWN_CONTEXT_LOST_ERROR("vkEnumerateInstanceExtensionProperties");
|
||||
}
|
||||
|
||||
info.extensions.resize(count);
|
||||
result = device.fn.EnumerateInstanceExtensionProperties(nullptr, &count,
|
||||
info.extensions.data());
|
||||
result = vkFunctions.EnumerateInstanceExtensionProperties(nullptr, &count,
|
||||
info.extensions.data());
|
||||
if (result != VK_SUCCESS) {
|
||||
return DAWN_CONTEXT_LOST_ERROR("vkEnumerateInstanceExtensionProperties");
|
||||
}
|
||||
@ -122,17 +124,18 @@ namespace dawn_native { namespace vulkan {
|
||||
return info;
|
||||
}
|
||||
|
||||
ResultOrError<std::vector<VkPhysicalDevice>> GetPhysicalDevices(const Device& device) {
|
||||
VkInstance instance = device.GetInstance();
|
||||
ResultOrError<std::vector<VkPhysicalDevice>> GetPhysicalDevices(const Backend& backend) {
|
||||
VkInstance instance = backend.GetVkInstance();
|
||||
const VulkanFunctions& vkFunctions = backend.GetFunctions();
|
||||
|
||||
uint32_t count = 0;
|
||||
VkResult result = device.fn.EnumeratePhysicalDevices(instance, &count, nullptr);
|
||||
VkResult result = vkFunctions.EnumeratePhysicalDevices(instance, &count, nullptr);
|
||||
if (result != VK_SUCCESS && result != VK_INCOMPLETE) {
|
||||
return DAWN_CONTEXT_LOST_ERROR("vkEnumeratePhysicalDevices");
|
||||
}
|
||||
|
||||
std::vector<VkPhysicalDevice> physicalDevices(count);
|
||||
result = device.fn.EnumeratePhysicalDevices(instance, &count, physicalDevices.data());
|
||||
result = vkFunctions.EnumeratePhysicalDevices(instance, &count, physicalDevices.data());
|
||||
if (result != VK_SUCCESS) {
|
||||
return DAWN_CONTEXT_LOST_ERROR("vkEnumeratePhysicalDevices");
|
||||
}
|
||||
@ -140,18 +143,19 @@ namespace dawn_native { namespace vulkan {
|
||||
return physicalDevices;
|
||||
}
|
||||
|
||||
ResultOrError<VulkanDeviceInfo> GatherDeviceInfo(const Device& device,
|
||||
VkPhysicalDevice physicalDevice) {
|
||||
ResultOrError<VulkanDeviceInfo> GatherDeviceInfo(const Adapter& adapter) {
|
||||
VulkanDeviceInfo info = {};
|
||||
VkPhysicalDevice physicalDevice = adapter.GetPhysicalDevice();
|
||||
const VulkanFunctions& vkFunctions = adapter.GetBackend()->GetFunctions();
|
||||
|
||||
// Gather general info about the device
|
||||
device.fn.GetPhysicalDeviceProperties(physicalDevice, &info.properties);
|
||||
device.fn.GetPhysicalDeviceFeatures(physicalDevice, &info.features);
|
||||
vkFunctions.GetPhysicalDeviceProperties(physicalDevice, &info.properties);
|
||||
vkFunctions.GetPhysicalDeviceFeatures(physicalDevice, &info.features);
|
||||
|
||||
// Gather info about device memory.
|
||||
{
|
||||
VkPhysicalDeviceMemoryProperties memory;
|
||||
device.fn.GetPhysicalDeviceMemoryProperties(physicalDevice, &memory);
|
||||
vkFunctions.GetPhysicalDeviceMemoryProperties(physicalDevice, &memory);
|
||||
|
||||
info.memoryTypes.assign(memory.memoryTypes,
|
||||
memory.memoryTypes + memory.memoryTypeCount);
|
||||
@ -162,25 +166,25 @@ namespace dawn_native { namespace vulkan {
|
||||
// Gather info about device queue families
|
||||
{
|
||||
uint32_t count = 0;
|
||||
device.fn.GetPhysicalDeviceQueueFamilyProperties(physicalDevice, &count, nullptr);
|
||||
vkFunctions.GetPhysicalDeviceQueueFamilyProperties(physicalDevice, &count, nullptr);
|
||||
|
||||
info.queueFamilies.resize(count);
|
||||
device.fn.GetPhysicalDeviceQueueFamilyProperties(physicalDevice, &count,
|
||||
info.queueFamilies.data());
|
||||
vkFunctions.GetPhysicalDeviceQueueFamilyProperties(physicalDevice, &count,
|
||||
info.queueFamilies.data());
|
||||
}
|
||||
|
||||
// Gather the info about the device layers
|
||||
{
|
||||
uint32_t count = 0;
|
||||
VkResult result =
|
||||
device.fn.EnumerateDeviceLayerProperties(physicalDevice, &count, nullptr);
|
||||
vkFunctions.EnumerateDeviceLayerProperties(physicalDevice, &count, nullptr);
|
||||
if (result != VK_SUCCESS && result != VK_INCOMPLETE) {
|
||||
return DAWN_CONTEXT_LOST_ERROR("vkEnumerateDeviceLayerProperties");
|
||||
}
|
||||
|
||||
info.layers.resize(count);
|
||||
result = device.fn.EnumerateDeviceLayerProperties(physicalDevice, &count,
|
||||
info.layers.data());
|
||||
result = vkFunctions.EnumerateDeviceLayerProperties(physicalDevice, &count,
|
||||
info.layers.data());
|
||||
if (result != VK_SUCCESS) {
|
||||
return DAWN_CONTEXT_LOST_ERROR("vkEnumerateDeviceLayerProperties");
|
||||
}
|
||||
@ -189,15 +193,15 @@ namespace dawn_native { namespace vulkan {
|
||||
// Gather the info about the device extensions
|
||||
{
|
||||
uint32_t count = 0;
|
||||
VkResult result = device.fn.EnumerateDeviceExtensionProperties(physicalDevice, nullptr,
|
||||
&count, nullptr);
|
||||
VkResult result = vkFunctions.EnumerateDeviceExtensionProperties(
|
||||
physicalDevice, nullptr, &count, nullptr);
|
||||
if (result != VK_SUCCESS && result != VK_INCOMPLETE) {
|
||||
return DAWN_CONTEXT_LOST_ERROR("vkEnumerateDeviceExtensionProperties");
|
||||
}
|
||||
|
||||
info.extensions.resize(count);
|
||||
result = device.fn.EnumerateDeviceExtensionProperties(physicalDevice, nullptr, &count,
|
||||
info.extensions.data());
|
||||
result = vkFunctions.EnumerateDeviceExtensionProperties(physicalDevice, nullptr, &count,
|
||||
info.extensions.data());
|
||||
if (result != VK_SUCCESS) {
|
||||
return DAWN_CONTEXT_LOST_ERROR("vkEnumerateDeviceExtensionProperties");
|
||||
}
|
||||
@ -214,14 +218,15 @@ namespace dawn_native { namespace vulkan {
|
||||
return info;
|
||||
}
|
||||
|
||||
MaybeError GatherSurfaceInfo(const Device& device,
|
||||
MaybeError GatherSurfaceInfo(const Adapter& adapter,
|
||||
VkSurfaceKHR surface,
|
||||
VulkanSurfaceInfo* info) {
|
||||
VkPhysicalDevice physicalDevice = device.GetPhysicalDevice();
|
||||
VkPhysicalDevice physicalDevice = adapter.GetPhysicalDevice();
|
||||
const VulkanFunctions& vkFunctions = adapter.GetBackend()->GetFunctions();
|
||||
|
||||
// Get the surface capabilities
|
||||
{
|
||||
VkResult result = device.fn.GetPhysicalDeviceSurfaceCapabilitiesKHR(
|
||||
VkResult result = vkFunctions.GetPhysicalDeviceSurfaceCapabilitiesKHR(
|
||||
physicalDevice, surface, &info->capabilities);
|
||||
if (result != VK_SUCCESS) {
|
||||
return DAWN_CONTEXT_LOST_ERROR("vkGetPhysicalDeviceSurfaceCapabilitiesKHR");
|
||||
@ -230,13 +235,13 @@ namespace dawn_native { namespace vulkan {
|
||||
|
||||
// Query which queue families support presenting this surface
|
||||
{
|
||||
size_t nQueueFamilies = device.GetDeviceInfo().queueFamilies.size();
|
||||
size_t nQueueFamilies = adapter.GetDeviceInfo().queueFamilies.size();
|
||||
info->supportedQueueFamilies.resize(nQueueFamilies, false);
|
||||
|
||||
for (uint32_t i = 0; i < nQueueFamilies; ++i) {
|
||||
VkBool32 supported = VK_FALSE;
|
||||
VkResult result = device.fn.GetPhysicalDeviceSurfaceSupportKHR(physicalDevice, i,
|
||||
surface, &supported);
|
||||
VkResult result = vkFunctions.GetPhysicalDeviceSurfaceSupportKHR(
|
||||
physicalDevice, i, surface, &supported);
|
||||
|
||||
if (result != VK_SUCCESS) {
|
||||
return DAWN_CONTEXT_LOST_ERROR("vkGetPhysicalDeviceSurfaceSupportKHR");
|
||||
@ -249,15 +254,15 @@ namespace dawn_native { namespace vulkan {
|
||||
// Gather supported formats
|
||||
{
|
||||
uint32_t count = 0;
|
||||
VkResult result = device.fn.GetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface,
|
||||
&count, nullptr);
|
||||
VkResult result = vkFunctions.GetPhysicalDeviceSurfaceFormatsKHR(
|
||||
physicalDevice, surface, &count, nullptr);
|
||||
if (result != VK_SUCCESS && result != VK_INCOMPLETE) {
|
||||
return DAWN_CONTEXT_LOST_ERROR("vkGetPhysicalDeviceSurfaceFormatsKHR");
|
||||
}
|
||||
|
||||
info->formats.resize(count);
|
||||
result = device.fn.GetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface, &count,
|
||||
info->formats.data());
|
||||
result = vkFunctions.GetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface, &count,
|
||||
info->formats.data());
|
||||
if (result != VK_SUCCESS) {
|
||||
return DAWN_CONTEXT_LOST_ERROR("vkGetPhysicalDeviceSurfaceFormatsKHR");
|
||||
}
|
||||
@ -266,14 +271,14 @@ namespace dawn_native { namespace vulkan {
|
||||
// Gather supported presents modes
|
||||
{
|
||||
uint32_t count = 0;
|
||||
VkResult result = device.fn.GetPhysicalDeviceSurfacePresentModesKHR(
|
||||
VkResult result = vkFunctions.GetPhysicalDeviceSurfacePresentModesKHR(
|
||||
physicalDevice, surface, &count, nullptr);
|
||||
if (result != VK_SUCCESS && result != VK_INCOMPLETE) {
|
||||
return DAWN_CONTEXT_LOST_ERROR("vkGetPhysicalDeviceSurfacePresentModesKHR");
|
||||
}
|
||||
|
||||
info->presentModes.resize(count);
|
||||
result = device.fn.GetPhysicalDeviceSurfacePresentModesKHR(
|
||||
result = vkFunctions.GetPhysicalDeviceSurfacePresentModesKHR(
|
||||
physicalDevice, surface, &count, info->presentModes.data());
|
||||
if (result != VK_SUCCESS) {
|
||||
return DAWN_CONTEXT_LOST_ERROR("vkGetPhysicalDeviceSurfacePresentModesKHR");
|
||||
|
@ -22,7 +22,8 @@
|
||||
|
||||
namespace dawn_native { namespace vulkan {
|
||||
|
||||
class Device;
|
||||
class Adapter;
|
||||
class Backend;
|
||||
|
||||
extern const char kLayerNameLunargStandardValidation[];
|
||||
extern const char kLayerNameLunargVKTrace[];
|
||||
@ -87,11 +88,10 @@ namespace dawn_native { namespace vulkan {
|
||||
std::vector<bool> supportedQueueFamilies;
|
||||
};
|
||||
|
||||
ResultOrError<VulkanGlobalInfo> GatherGlobalInfo(const Device& device);
|
||||
ResultOrError<std::vector<VkPhysicalDevice>> GetPhysicalDevices(const Device& device);
|
||||
ResultOrError<VulkanDeviceInfo> GatherDeviceInfo(const Device& device,
|
||||
VkPhysicalDevice physicalDevice);
|
||||
MaybeError GatherSurfaceInfo(const Device& device,
|
||||
ResultOrError<VulkanGlobalInfo> GatherGlobalInfo(const Backend& backend);
|
||||
ResultOrError<std::vector<VkPhysicalDevice>> GetPhysicalDevices(const Backend& backend);
|
||||
ResultOrError<VulkanDeviceInfo> GatherDeviceInfo(const Adapter& adapter);
|
||||
MaybeError GatherSurfaceInfo(const Adapter& adapter,
|
||||
VkSurfaceKHR surface,
|
||||
VulkanSurfaceInfo* info);
|
||||
}} // namespace dawn_native::vulkan
|
||||
|
@ -15,17 +15,14 @@
|
||||
#ifndef DAWNNATIVE_VULKANBACKEND_H_
|
||||
#define DAWNNATIVE_VULKANBACKEND_H_
|
||||
|
||||
#include <dawn/dawn.h>
|
||||
#include <dawn/dawn_wsi.h>
|
||||
#include <dawn_native/dawn_native_export.h>
|
||||
#include <dawn_native/DawnNative.h>
|
||||
|
||||
#include <vulkan/vulkan.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace dawn_native { namespace vulkan {
|
||||
DAWN_NATIVE_EXPORT dawnDevice CreateDevice();
|
||||
|
||||
DAWN_NATIVE_EXPORT VkInstance GetInstance(dawnDevice device);
|
||||
|
||||
DAWN_NATIVE_EXPORT dawnSwapChainImplementation CreateNativeSwapChainImpl(dawnDevice device,
|
||||
|
@ -28,8 +28,20 @@ namespace utils {
|
||||
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
|
||||
}
|
||||
dawnDevice CreateDevice() override {
|
||||
mDevice = dawn_native::vulkan::CreateDevice();
|
||||
return mDevice;
|
||||
// Make an instance and find a Vulkan adapter
|
||||
mInstance = std::make_unique<dawn_native::Instance>();
|
||||
mInstance->DiscoverDefaultAdapters();
|
||||
|
||||
std::vector<dawn_native::Adapter> adapters = mInstance->GetAdapters();
|
||||
for (dawn_native::Adapter adapter : adapters) {
|
||||
if (adapter.GetBackendType() == dawn_native::BackendType::Vulkan) {
|
||||
mDevice = adapter.CreateDevice();
|
||||
return mDevice;
|
||||
}
|
||||
}
|
||||
|
||||
UNREACHABLE();
|
||||
return {};
|
||||
}
|
||||
uint64_t GetSwapChainImplementation() override {
|
||||
if (mSwapchainImpl.userData == nullptr) {
|
||||
@ -49,7 +61,8 @@ namespace utils {
|
||||
}
|
||||
|
||||
private:
|
||||
dawnDevice mDevice;
|
||||
std::unique_ptr<dawn_native::Instance> mInstance;
|
||||
dawnDevice mDevice = nullptr;
|
||||
dawnSwapChainImplementation mSwapchainImpl = {};
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user