mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-07-14 00:56:05 +00:00
Vulkan: Handle errors on device creation.
This is both something we should strive for for robustness of the backends and in this case helped debug what the issue was on the linux-dawn-rel builder that was failing all Vulkan tests. BUG=dawn:19 Change-Id: Ibe9f5ad76b7766575bb74fe4993625cf82cdf13f Reviewed-on: https://dawn-review.googlesource.com/c/2702 Commit-Queue: Corentin Wallez <cwallez@chromium.org> Reviewed-by: Kai Ninomiya <kainino@chromium.org>
This commit is contained in:
parent
0f8b507888
commit
85df07a1e5
@ -19,7 +19,7 @@
|
||||
namespace dawn_native {
|
||||
|
||||
ErrorData* MakeError(ErrorType type,
|
||||
const char* message,
|
||||
std::string message,
|
||||
const char* file,
|
||||
const char* function,
|
||||
int line) {
|
||||
|
@ -17,6 +17,8 @@
|
||||
|
||||
#include "common/Result.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace dawn_native {
|
||||
|
||||
// This is the content of an error value for MaybeError or ResultOrError, split off to its own
|
||||
@ -85,7 +87,7 @@ namespace dawn_native {
|
||||
|
||||
// Implementation detail of DAWN_MAKE_ERROR
|
||||
ErrorData* MakeError(ErrorType type,
|
||||
const char* message,
|
||||
std::string message,
|
||||
const char* file,
|
||||
const char* function,
|
||||
int line);
|
||||
|
@ -83,66 +83,47 @@ namespace dawn_native { namespace vulkan {
|
||||
// Device
|
||||
|
||||
Device::Device(const std::vector<const char*>& requiredInstanceExtensions) {
|
||||
if (!mVulkanLib.Open(kVulkanLibName)) {
|
||||
if (ConsumedError(Initialize(requiredInstanceExtensions))) {
|
||||
ASSERT(false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
MaybeError Device::Initialize(const std::vector<const char*>& requiredInstanceExtensions) {
|
||||
if (!mVulkanLib.Open(kVulkanLibName)) {
|
||||
return DAWN_CONTEXT_LOST_ERROR(std::string("Couldn't open ") + kVulkanLibName);
|
||||
}
|
||||
|
||||
VulkanFunctions* functions = GetMutableFunctions();
|
||||
DAWN_TRY(functions->LoadGlobalProcs(mVulkanLib));
|
||||
|
||||
if (!functions->LoadGlobalProcs(mVulkanLib)) {
|
||||
ASSERT(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!GatherGlobalInfo(*this, &mGlobalInfo)) {
|
||||
ASSERT(false);
|
||||
return;
|
||||
}
|
||||
DAWN_TRY_ASSIGN(mGlobalInfo, GatherGlobalInfo(*this));
|
||||
|
||||
VulkanGlobalKnobs usedGlobalKnobs = {};
|
||||
if (!CreateInstance(&usedGlobalKnobs, requiredInstanceExtensions)) {
|
||||
ASSERT(false);
|
||||
return;
|
||||
}
|
||||
DAWN_TRY_ASSIGN(usedGlobalKnobs, CreateInstance(requiredInstanceExtensions));
|
||||
*static_cast<VulkanGlobalKnobs*>(&mGlobalInfo) = usedGlobalKnobs;
|
||||
|
||||
if (!functions->LoadInstanceProcs(mInstance, usedGlobalKnobs)) {
|
||||
ASSERT(false);
|
||||
return;
|
||||
}
|
||||
DAWN_TRY(functions->LoadInstanceProcs(mInstance, mGlobalInfo));
|
||||
|
||||
if (usedGlobalKnobs.debugReport) {
|
||||
if (!RegisterDebugReport()) {
|
||||
ASSERT(false);
|
||||
return;
|
||||
}
|
||||
DAWN_TRY(RegisterDebugReport());
|
||||
}
|
||||
|
||||
std::vector<VkPhysicalDevice> physicalDevices;
|
||||
if (!GetPhysicalDevices(*this, &physicalDevices) || physicalDevices.empty()) {
|
||||
ASSERT(false);
|
||||
return;
|
||||
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];
|
||||
|
||||
if (!GatherDeviceInfo(*this, mPhysicalDevice, &mDeviceInfo)) {
|
||||
ASSERT(false);
|
||||
return;
|
||||
}
|
||||
DAWN_TRY_ASSIGN(mDeviceInfo, GatherDeviceInfo(*this, mPhysicalDevice));
|
||||
|
||||
VulkanDeviceKnobs usedDeviceKnobs = {};
|
||||
if (!CreateDevice(&usedDeviceKnobs)) {
|
||||
ASSERT(false);
|
||||
return;
|
||||
}
|
||||
DAWN_TRY_ASSIGN(usedDeviceKnobs, CreateDevice());
|
||||
*static_cast<VulkanDeviceKnobs*>(&mDeviceInfo) = usedDeviceKnobs;
|
||||
|
||||
if (!functions->LoadDeviceProcs(mVkDevice, usedDeviceKnobs)) {
|
||||
ASSERT(false);
|
||||
return;
|
||||
}
|
||||
DAWN_TRY(functions->LoadDeviceProcs(mVkDevice, mDeviceInfo));
|
||||
|
||||
GatherQueueFromDevice();
|
||||
|
||||
@ -155,6 +136,8 @@ namespace dawn_native { namespace vulkan {
|
||||
mPCIInfo.deviceId = mDeviceInfo.properties.deviceID;
|
||||
mPCIInfo.vendorId = mDeviceInfo.properties.vendorID;
|
||||
mPCIInfo.name = mDeviceInfo.properties.deviceName;
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
Device::~Device() {
|
||||
@ -418,8 +401,10 @@ namespace dawn_native { namespace vulkan {
|
||||
mWaitSemaphores.push_back(semaphore);
|
||||
}
|
||||
|
||||
bool Device::CreateInstance(VulkanGlobalKnobs* usedKnobs,
|
||||
const std::vector<const char*>& requiredExtensions) {
|
||||
ResultOrError<VulkanGlobalKnobs> Device::CreateInstance(
|
||||
const std::vector<const char*>& requiredExtensions) {
|
||||
VulkanGlobalKnobs usedKnobs = {};
|
||||
|
||||
std::vector<const char*> layersToRequest;
|
||||
std::vector<const char*> extensionsToRequest = requiredExtensions;
|
||||
|
||||
@ -441,7 +426,7 @@ namespace dawn_native { namespace vulkan {
|
||||
#if defined(DAWN_USE_VKTRACE)
|
||||
if (mGlobalInfo.vktrace) {
|
||||
layersToRequest.push_back(kLayerNameLunargVKTrace);
|
||||
usedKnobs->vktrace = true;
|
||||
usedKnobs.vktrace = true;
|
||||
}
|
||||
#endif
|
||||
// RenderDoc installs a layer at the system level for its capture but we don't want to use
|
||||
@ -449,22 +434,22 @@ namespace dawn_native { namespace vulkan {
|
||||
#if defined(DAWN_USE_RENDERDOC)
|
||||
if (mGlobalInfo.renderDocCapture) {
|
||||
layersToRequest.push_back(kLayerNameRenderDocCapture);
|
||||
usedKnobs->renderDocCapture = true;
|
||||
usedKnobs.renderDocCapture = true;
|
||||
}
|
||||
#endif
|
||||
#if defined(DAWN_ENABLE_ASSERTS)
|
||||
if (mGlobalInfo.standardValidation) {
|
||||
layersToRequest.push_back(kLayerNameLunargStandardValidation);
|
||||
usedKnobs->standardValidation = true;
|
||||
usedKnobs.standardValidation = true;
|
||||
}
|
||||
if (mGlobalInfo.debugReport) {
|
||||
AddExtensionIfNotPresent(&extensionsToRequest, kExtensionNameExtDebugReport);
|
||||
usedKnobs->debugReport = true;
|
||||
usedKnobs.debugReport = true;
|
||||
}
|
||||
#endif
|
||||
if (mGlobalInfo.surface) {
|
||||
AddExtensionIfNotPresent(&extensionsToRequest, kExtensionNameKhrSurface);
|
||||
usedKnobs->surface = true;
|
||||
usedKnobs.surface = true;
|
||||
}
|
||||
|
||||
VkApplicationInfo appInfo;
|
||||
@ -487,13 +472,15 @@ namespace dawn_native { namespace vulkan {
|
||||
createInfo.ppEnabledExtensionNames = extensionsToRequest.data();
|
||||
|
||||
if (fn.CreateInstance(&createInfo, nullptr, &mInstance) != VK_SUCCESS) {
|
||||
return false;
|
||||
return DAWN_CONTEXT_LOST_ERROR("vkCreateInstance failed");
|
||||
}
|
||||
|
||||
return true;
|
||||
return usedKnobs;
|
||||
}
|
||||
|
||||
bool Device::CreateDevice(VulkanDeviceKnobs* usedKnobs) {
|
||||
ResultOrError<VulkanDeviceKnobs> Device::CreateDevice() {
|
||||
VulkanDeviceKnobs usedKnobs = {};
|
||||
|
||||
float zero = 0.0f;
|
||||
std::vector<const char*> layersToRequest;
|
||||
std::vector<const char*> extensionsToRequest;
|
||||
@ -501,13 +488,13 @@ namespace dawn_native { namespace vulkan {
|
||||
|
||||
if (mDeviceInfo.swapchain) {
|
||||
extensionsToRequest.push_back(kExtensionNameKhrSwapchain);
|
||||
usedKnobs->swapchain = true;
|
||||
usedKnobs.swapchain = true;
|
||||
}
|
||||
|
||||
// Always require independentBlend because it is a core Dawn feature
|
||||
usedKnobs->features.independentBlend = VK_TRUE;
|
||||
usedKnobs.features.independentBlend = VK_TRUE;
|
||||
// Always require imageCubeArray because it is a core Dawn feature
|
||||
usedKnobs->features.imageCubeArray = VK_TRUE;
|
||||
usedKnobs.features.imageCubeArray = VK_TRUE;
|
||||
|
||||
// Find a universal queue family
|
||||
{
|
||||
@ -523,7 +510,7 @@ namespace dawn_native { namespace vulkan {
|
||||
}
|
||||
|
||||
if (universalQueueFamily == -1) {
|
||||
return false;
|
||||
return DAWN_CONTEXT_LOST_ERROR("No universal queue family");
|
||||
}
|
||||
mQueueFamily = static_cast<uint32_t>(universalQueueFamily);
|
||||
}
|
||||
@ -551,20 +538,20 @@ namespace dawn_native { namespace vulkan {
|
||||
createInfo.ppEnabledLayerNames = layersToRequest.data();
|
||||
createInfo.enabledExtensionCount = static_cast<uint32_t>(extensionsToRequest.size());
|
||||
createInfo.ppEnabledExtensionNames = extensionsToRequest.data();
|
||||
createInfo.pEnabledFeatures = &usedKnobs->features;
|
||||
createInfo.pEnabledFeatures = &usedKnobs.features;
|
||||
|
||||
if (fn.CreateDevice(mPhysicalDevice, &createInfo, nullptr, &mVkDevice) != VK_SUCCESS) {
|
||||
return false;
|
||||
return DAWN_CONTEXT_LOST_ERROR("vkCreateDevice failed");
|
||||
}
|
||||
|
||||
return true;
|
||||
return usedKnobs;
|
||||
}
|
||||
|
||||
void Device::GatherQueueFromDevice() {
|
||||
fn.GetDeviceQueue(mVkDevice, mQueueFamily, 0, &mQueue);
|
||||
}
|
||||
|
||||
bool Device::RegisterDebugReport() {
|
||||
MaybeError Device::RegisterDebugReport() {
|
||||
VkDebugReportCallbackCreateInfoEXT createInfo;
|
||||
createInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT;
|
||||
createInfo.pNext = nullptr;
|
||||
@ -574,10 +561,10 @@ namespace dawn_native { namespace vulkan {
|
||||
|
||||
if (fn.CreateDebugReportCallbackEXT(mInstance, &createInfo, nullptr,
|
||||
&mDebugReportCallback) != VK_SUCCESS) {
|
||||
return false;
|
||||
return DAWN_CONTEXT_LOST_ERROR("vkCreateDebugReportCallbackEXT failed");
|
||||
}
|
||||
|
||||
return true;
|
||||
return {};
|
||||
}
|
||||
|
||||
VKAPI_ATTR VkBool32 VKAPI_CALL
|
||||
|
@ -97,12 +97,13 @@ namespace dawn_native { namespace vulkan {
|
||||
TextureBase* texture,
|
||||
const TextureViewDescriptor* descriptor) override;
|
||||
|
||||
bool CreateInstance(VulkanGlobalKnobs* usedKnobs,
|
||||
const std::vector<const char*>& requiredExtensions);
|
||||
bool CreateDevice(VulkanDeviceKnobs* usedKnobs);
|
||||
MaybeError Initialize(const std::vector<const char*>& requiredInstanceExtensions);
|
||||
ResultOrError<VulkanGlobalKnobs> CreateInstance(
|
||||
const std::vector<const char*>& requiredExtensions);
|
||||
ResultOrError<VulkanDeviceKnobs> CreateDevice();
|
||||
void GatherQueueFromDevice();
|
||||
|
||||
bool RegisterDebugReport();
|
||||
MaybeError RegisterDebugReport();
|
||||
static VKAPI_ATTR VkBool32 VKAPI_CALL
|
||||
OnDebugReportCallback(VkDebugReportFlagsEXT flags,
|
||||
VkDebugReportObjectTypeEXT objectType,
|
||||
@ -117,8 +118,8 @@ namespace dawn_native { namespace vulkan {
|
||||
// the Device is allowed to mutate them through these private methods.
|
||||
VulkanFunctions* GetMutableFunctions();
|
||||
|
||||
VulkanGlobalInfo mGlobalInfo;
|
||||
VulkanDeviceInfo mDeviceInfo;
|
||||
VulkanGlobalInfo mGlobalInfo = {};
|
||||
VulkanDeviceInfo mDeviceInfo = {};
|
||||
|
||||
DynamicLib mVulkanLib;
|
||||
|
||||
|
@ -58,7 +58,7 @@ namespace dawn_native { namespace vulkan {
|
||||
}
|
||||
|
||||
void NativeSwapChainImpl::Init(dawnWSIContextVulkan* /*context*/) {
|
||||
if (!GatherSurfaceInfo(*mDevice, mSurface, &mInfo)) {
|
||||
if (mDevice->ConsumedError(GatherSurfaceInfo(*mDevice, mSurface, &mInfo))) {
|
||||
ASSERT(false);
|
||||
}
|
||||
|
||||
|
@ -22,29 +22,29 @@ namespace dawn_native { namespace vulkan {
|
||||
#define GET_GLOBAL_PROC(name) \
|
||||
name = reinterpret_cast<decltype(name)>(GetInstanceProcAddr(nullptr, "vk" #name)); \
|
||||
if (name == nullptr) { \
|
||||
return false; \
|
||||
return DAWN_CONTEXT_LOST_ERROR(std::string("Couldn't get proc vk") + #name); \
|
||||
}
|
||||
|
||||
bool VulkanFunctions::LoadGlobalProcs(const DynamicLib& vulkanLib) {
|
||||
MaybeError VulkanFunctions::LoadGlobalProcs(const DynamicLib& vulkanLib) {
|
||||
if (!vulkanLib.GetProc(&GetInstanceProcAddr, "vkGetInstanceProcAddr")) {
|
||||
return false;
|
||||
return DAWN_CONTEXT_LOST_ERROR("Couldn't get vkGetInstanceProcAddr");
|
||||
}
|
||||
|
||||
GET_GLOBAL_PROC(CreateInstance);
|
||||
GET_GLOBAL_PROC(EnumerateInstanceExtensionProperties);
|
||||
GET_GLOBAL_PROC(EnumerateInstanceLayerProperties);
|
||||
|
||||
return true;
|
||||
return {};
|
||||
}
|
||||
|
||||
#define GET_INSTANCE_PROC(name) \
|
||||
name = reinterpret_cast<decltype(name)>(GetInstanceProcAddr(instance, "vk" #name)); \
|
||||
if (name == nullptr) { \
|
||||
return false; \
|
||||
return DAWN_CONTEXT_LOST_ERROR(std::string("Couldn't get proc vk") + #name); \
|
||||
}
|
||||
|
||||
bool VulkanFunctions::LoadInstanceProcs(VkInstance instance,
|
||||
const VulkanGlobalKnobs& usedKnobs) {
|
||||
MaybeError VulkanFunctions::LoadInstanceProcs(VkInstance instance,
|
||||
const VulkanGlobalKnobs& usedKnobs) {
|
||||
// Load this proc first so that we can destroy the instance even if some other
|
||||
// GET_INSTANCE_PROC fails
|
||||
GET_INSTANCE_PROC(DestroyInstance);
|
||||
@ -77,16 +77,17 @@ namespace dawn_native { namespace vulkan {
|
||||
GET_INSTANCE_PROC(GetPhysicalDeviceSurfacePresentModesKHR);
|
||||
}
|
||||
|
||||
return true;
|
||||
return {};
|
||||
}
|
||||
|
||||
#define GET_DEVICE_PROC(name) \
|
||||
name = reinterpret_cast<decltype(name)>(GetDeviceProcAddr(device, "vk" #name)); \
|
||||
if (name == nullptr) { \
|
||||
return false; \
|
||||
#define GET_DEVICE_PROC(name) \
|
||||
name = reinterpret_cast<decltype(name)>(GetDeviceProcAddr(device, "vk" #name)); \
|
||||
if (name == nullptr) { \
|
||||
return DAWN_CONTEXT_LOST_ERROR(std::string("Couldn't get proc vk") + #name); \
|
||||
}
|
||||
|
||||
bool VulkanFunctions::LoadDeviceProcs(VkDevice device, const VulkanDeviceKnobs& usedKnobs) {
|
||||
MaybeError VulkanFunctions::LoadDeviceProcs(VkDevice device,
|
||||
const VulkanDeviceKnobs& usedKnobs) {
|
||||
GET_DEVICE_PROC(AllocateCommandBuffers);
|
||||
GET_DEVICE_PROC(AllocateDescriptorSets);
|
||||
GET_DEVICE_PROC(AllocateMemory);
|
||||
@ -215,7 +216,7 @@ namespace dawn_native { namespace vulkan {
|
||||
GET_DEVICE_PROC(QueuePresentKHR);
|
||||
}
|
||||
|
||||
return true;
|
||||
return {};
|
||||
}
|
||||
|
||||
}} // namespace dawn_native::vulkan
|
||||
|
@ -17,6 +17,8 @@
|
||||
|
||||
#include "common/vulkan_platform.h"
|
||||
|
||||
#include "dawn_native/Error.h"
|
||||
|
||||
class DynamicLib;
|
||||
|
||||
namespace dawn_native { namespace vulkan {
|
||||
@ -27,9 +29,9 @@ namespace dawn_native { namespace vulkan {
|
||||
// Stores the Vulkan entry points. Also loads them from the dynamic library
|
||||
// and the vkGet*ProcAddress entry points.
|
||||
struct VulkanFunctions {
|
||||
bool LoadGlobalProcs(const DynamicLib& vulkanLib);
|
||||
bool LoadInstanceProcs(VkInstance instance, const VulkanGlobalKnobs& usedGlobals);
|
||||
bool LoadDeviceProcs(VkDevice device, const VulkanDeviceKnobs& usedKnobs);
|
||||
MaybeError LoadGlobalProcs(const DynamicLib& vulkanLib);
|
||||
MaybeError LoadInstanceProcs(VkInstance instance, const VulkanGlobalKnobs& usedGlobals);
|
||||
MaybeError LoadDeviceProcs(VkDevice device, const VulkanDeviceKnobs& usedKnobs);
|
||||
|
||||
// ---------- Global procs
|
||||
|
||||
|
@ -38,7 +38,9 @@ namespace dawn_native { namespace vulkan {
|
||||
const char kExtensionNameKhrSurface[] = "VK_KHR_surface";
|
||||
const char kExtensionNameKhrSwapchain[] = "VK_KHR_swapchain";
|
||||
|
||||
bool GatherGlobalInfo(const Device& device, VulkanGlobalInfo* info) {
|
||||
ResultOrError<VulkanGlobalInfo> GatherGlobalInfo(const Device& device) {
|
||||
VulkanGlobalInfo info = {};
|
||||
|
||||
// Gather the info about the instance layers
|
||||
{
|
||||
uint32_t count = 0;
|
||||
@ -47,24 +49,24 @@ namespace dawn_native { namespace vulkan {
|
||||
// incomplete otherwise. This means that both values represent a success.
|
||||
// This is the same for all Enumarte functions
|
||||
if (result != VK_SUCCESS && result != VK_INCOMPLETE) {
|
||||
return false;
|
||||
return DAWN_CONTEXT_LOST_ERROR("vkEnumerateInstanceLayerProperties");
|
||||
}
|
||||
|
||||
info->layers.resize(count);
|
||||
result = device.fn.EnumerateInstanceLayerProperties(&count, info->layers.data());
|
||||
info.layers.resize(count);
|
||||
result = device.fn.EnumerateInstanceLayerProperties(&count, info.layers.data());
|
||||
if (result != VK_SUCCESS) {
|
||||
return false;
|
||||
return DAWN_CONTEXT_LOST_ERROR("vkEnumerateInstanceLayerProperties");
|
||||
}
|
||||
|
||||
for (const auto& layer : info->layers) {
|
||||
for (const auto& layer : info.layers) {
|
||||
if (IsLayerName(layer, kLayerNameLunargStandardValidation)) {
|
||||
info->standardValidation = true;
|
||||
info.standardValidation = true;
|
||||
}
|
||||
if (IsLayerName(layer, kLayerNameLunargVKTrace)) {
|
||||
info->vktrace = true;
|
||||
info.vktrace = true;
|
||||
}
|
||||
if (IsLayerName(layer, kLayerNameRenderDocCapture)) {
|
||||
info->renderDocCapture = true;
|
||||
info.renderDocCapture = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -75,65 +77,66 @@ namespace dawn_native { namespace vulkan {
|
||||
VkResult result =
|
||||
device.fn.EnumerateInstanceExtensionProperties(nullptr, &count, nullptr);
|
||||
if (result != VK_SUCCESS && result != VK_INCOMPLETE) {
|
||||
return false;
|
||||
return DAWN_CONTEXT_LOST_ERROR("vkEnumerateInstanceExtensionProperties");
|
||||
}
|
||||
|
||||
info->extensions.resize(count);
|
||||
info.extensions.resize(count);
|
||||
result = device.fn.EnumerateInstanceExtensionProperties(nullptr, &count,
|
||||
info->extensions.data());
|
||||
info.extensions.data());
|
||||
if (result != VK_SUCCESS) {
|
||||
return false;
|
||||
return DAWN_CONTEXT_LOST_ERROR("vkEnumerateInstanceExtensionProperties");
|
||||
}
|
||||
|
||||
for (const auto& extension : info->extensions) {
|
||||
for (const auto& extension : info.extensions) {
|
||||
if (IsExtensionName(extension, kExtensionNameExtDebugReport)) {
|
||||
info->debugReport = true;
|
||||
info.debugReport = true;
|
||||
}
|
||||
if (IsExtensionName(extension, kExtensionNameKhrSurface)) {
|
||||
info->surface = true;
|
||||
info.surface = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(cwallez@chromium:org): Each layer can expose additional extensions, query them?
|
||||
|
||||
return true;
|
||||
return info;
|
||||
}
|
||||
|
||||
bool GetPhysicalDevices(const Device& device, std::vector<VkPhysicalDevice>* physicalDevices) {
|
||||
ResultOrError<std::vector<VkPhysicalDevice>> GetPhysicalDevices(const Device& device) {
|
||||
VkInstance instance = device.GetInstance();
|
||||
|
||||
uint32_t count = 0;
|
||||
VkResult result = device.fn.EnumeratePhysicalDevices(instance, &count, nullptr);
|
||||
if (result != VK_SUCCESS && result != VK_INCOMPLETE) {
|
||||
return false;
|
||||
return DAWN_CONTEXT_LOST_ERROR("vkEnumeratePhysicalDevices");
|
||||
}
|
||||
|
||||
physicalDevices->resize(count);
|
||||
result = device.fn.EnumeratePhysicalDevices(instance, &count, physicalDevices->data());
|
||||
std::vector<VkPhysicalDevice> physicalDevices(count);
|
||||
result = device.fn.EnumeratePhysicalDevices(instance, &count, physicalDevices.data());
|
||||
if (result != VK_SUCCESS) {
|
||||
return false;
|
||||
return DAWN_CONTEXT_LOST_ERROR("vkEnumeratePhysicalDevices");
|
||||
}
|
||||
|
||||
return true;
|
||||
return physicalDevices;
|
||||
}
|
||||
|
||||
bool GatherDeviceInfo(const Device& device,
|
||||
VkPhysicalDevice physicalDevice,
|
||||
VulkanDeviceInfo* info) {
|
||||
ResultOrError<VulkanDeviceInfo> GatherDeviceInfo(const Device& device,
|
||||
VkPhysicalDevice physicalDevice) {
|
||||
VulkanDeviceInfo info = {};
|
||||
|
||||
// Gather general info about the device
|
||||
device.fn.GetPhysicalDeviceProperties(physicalDevice, &info->properties);
|
||||
device.fn.GetPhysicalDeviceFeatures(physicalDevice, &info->features);
|
||||
device.fn.GetPhysicalDeviceProperties(physicalDevice, &info.properties);
|
||||
device.fn.GetPhysicalDeviceFeatures(physicalDevice, &info.features);
|
||||
|
||||
// Gather info about device memory.
|
||||
{
|
||||
VkPhysicalDeviceMemoryProperties memory;
|
||||
device.fn.GetPhysicalDeviceMemoryProperties(physicalDevice, &memory);
|
||||
|
||||
info->memoryTypes.assign(memory.memoryTypes,
|
||||
memory.memoryTypes + memory.memoryTypeCount);
|
||||
info->memoryHeaps.assign(memory.memoryHeaps,
|
||||
memory.memoryHeaps + memory.memoryHeapCount);
|
||||
info.memoryTypes.assign(memory.memoryTypes,
|
||||
memory.memoryTypes + memory.memoryTypeCount);
|
||||
info.memoryHeaps.assign(memory.memoryHeaps,
|
||||
memory.memoryHeaps + memory.memoryHeapCount);
|
||||
}
|
||||
|
||||
// Gather info about device queue families
|
||||
@ -141,9 +144,9 @@ namespace dawn_native { namespace vulkan {
|
||||
uint32_t count = 0;
|
||||
device.fn.GetPhysicalDeviceQueueFamilyProperties(physicalDevice, &count, nullptr);
|
||||
|
||||
info->queueFamilies.resize(count);
|
||||
info.queueFamilies.resize(count);
|
||||
device.fn.GetPhysicalDeviceQueueFamilyProperties(physicalDevice, &count,
|
||||
info->queueFamilies.data());
|
||||
info.queueFamilies.data());
|
||||
}
|
||||
|
||||
// Gather the info about the device layers
|
||||
@ -152,14 +155,14 @@ namespace dawn_native { namespace vulkan {
|
||||
VkResult result =
|
||||
device.fn.EnumerateDeviceLayerProperties(physicalDevice, &count, nullptr);
|
||||
if (result != VK_SUCCESS && result != VK_INCOMPLETE) {
|
||||
return false;
|
||||
return DAWN_CONTEXT_LOST_ERROR("vkEnumerateDeviceLayerProperties");
|
||||
}
|
||||
|
||||
info->layers.resize(count);
|
||||
info.layers.resize(count);
|
||||
result = device.fn.EnumerateDeviceLayerProperties(physicalDevice, &count,
|
||||
info->layers.data());
|
||||
info.layers.data());
|
||||
if (result != VK_SUCCESS) {
|
||||
return false;
|
||||
return DAWN_CONTEXT_LOST_ERROR("vkEnumerateDeviceLayerProperties");
|
||||
}
|
||||
}
|
||||
|
||||
@ -169,29 +172,31 @@ namespace dawn_native { namespace vulkan {
|
||||
VkResult result = device.fn.EnumerateDeviceExtensionProperties(physicalDevice, nullptr,
|
||||
&count, nullptr);
|
||||
if (result != VK_SUCCESS && result != VK_INCOMPLETE) {
|
||||
return false;
|
||||
return DAWN_CONTEXT_LOST_ERROR("vkEnumerateDeviceExtensionProperties");
|
||||
}
|
||||
|
||||
info->extensions.resize(count);
|
||||
info.extensions.resize(count);
|
||||
result = device.fn.EnumerateDeviceExtensionProperties(physicalDevice, nullptr, &count,
|
||||
info->extensions.data());
|
||||
info.extensions.data());
|
||||
if (result != VK_SUCCESS) {
|
||||
return false;
|
||||
return DAWN_CONTEXT_LOST_ERROR("vkEnumerateDeviceExtensionProperties");
|
||||
}
|
||||
|
||||
for (const auto& extension : info->extensions) {
|
||||
for (const auto& extension : info.extensions) {
|
||||
if (IsExtensionName(extension, kExtensionNameKhrSwapchain)) {
|
||||
info->swapchain = true;
|
||||
info.swapchain = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(cwallez@chromium.org): gather info about formats
|
||||
|
||||
return true;
|
||||
return info;
|
||||
}
|
||||
|
||||
bool GatherSurfaceInfo(const Device& device, VkSurfaceKHR surface, VulkanSurfaceInfo* info) {
|
||||
MaybeError GatherSurfaceInfo(const Device& device,
|
||||
VkSurfaceKHR surface,
|
||||
VulkanSurfaceInfo* info) {
|
||||
VkPhysicalDevice physicalDevice = device.GetPhysicalDevice();
|
||||
|
||||
// Get the surface capabilities
|
||||
@ -199,7 +204,7 @@ namespace dawn_native { namespace vulkan {
|
||||
VkResult result = device.fn.GetPhysicalDeviceSurfaceCapabilitiesKHR(
|
||||
physicalDevice, surface, &info->capabilities);
|
||||
if (result != VK_SUCCESS) {
|
||||
return false;
|
||||
return DAWN_CONTEXT_LOST_ERROR("vkGetPhysicalDeviceSurfaceCapabilitiesKHR");
|
||||
}
|
||||
}
|
||||
|
||||
@ -214,7 +219,7 @@ namespace dawn_native { namespace vulkan {
|
||||
surface, &supported);
|
||||
|
||||
if (result != VK_SUCCESS) {
|
||||
return false;
|
||||
return DAWN_CONTEXT_LOST_ERROR("vkGetPhysicalDeviceSurfaceSupportKHR");
|
||||
}
|
||||
|
||||
info->supportedQueueFamilies[i] = (supported == VK_TRUE);
|
||||
@ -227,14 +232,14 @@ namespace dawn_native { namespace vulkan {
|
||||
VkResult result = device.fn.GetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface,
|
||||
&count, nullptr);
|
||||
if (result != VK_SUCCESS && result != VK_INCOMPLETE) {
|
||||
return false;
|
||||
return DAWN_CONTEXT_LOST_ERROR("vkGetPhysicalDeviceSurfaceFormatsKHR");
|
||||
}
|
||||
|
||||
info->formats.resize(count);
|
||||
result = device.fn.GetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface, &count,
|
||||
info->formats.data());
|
||||
if (result != VK_SUCCESS) {
|
||||
return false;
|
||||
return DAWN_CONTEXT_LOST_ERROR("vkGetPhysicalDeviceSurfaceFormatsKHR");
|
||||
}
|
||||
}
|
||||
|
||||
@ -244,18 +249,18 @@ namespace dawn_native { namespace vulkan {
|
||||
VkResult result = device.fn.GetPhysicalDeviceSurfacePresentModesKHR(
|
||||
physicalDevice, surface, &count, nullptr);
|
||||
if (result != VK_SUCCESS && result != VK_INCOMPLETE) {
|
||||
return false;
|
||||
return DAWN_CONTEXT_LOST_ERROR("vkGetPhysicalDeviceSurfacePresentModesKHR");
|
||||
}
|
||||
|
||||
info->presentModes.resize(count);
|
||||
result = device.fn.GetPhysicalDeviceSurfacePresentModesKHR(
|
||||
physicalDevice, surface, &count, info->presentModes.data());
|
||||
if (result != VK_SUCCESS) {
|
||||
return false;
|
||||
return DAWN_CONTEXT_LOST_ERROR("vkGetPhysicalDeviceSurfacePresentModesKHR");
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
return {};
|
||||
}
|
||||
|
||||
}} // namespace dawn_native::vulkan
|
||||
|
@ -16,6 +16,7 @@
|
||||
#define DAWNNATIVE_VULKAN_VULKANINFO_H_
|
||||
|
||||
#include "common/vulkan_platform.h"
|
||||
#include "dawn_native/Error.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
@ -76,13 +77,13 @@ namespace dawn_native { namespace vulkan {
|
||||
std::vector<bool> supportedQueueFamilies;
|
||||
};
|
||||
|
||||
bool GatherGlobalInfo(const Device& device, VulkanGlobalInfo* info);
|
||||
bool GetPhysicalDevices(const Device& device, std::vector<VkPhysicalDevice>* physicalDevices);
|
||||
bool GatherDeviceInfo(const Device& device,
|
||||
VkPhysicalDevice physicalDevice,
|
||||
VulkanDeviceInfo* info);
|
||||
bool GatherSurfaceInfo(const Device& device, VkSurfaceKHR surface, VulkanSurfaceInfo* info);
|
||||
|
||||
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,
|
||||
VkSurfaceKHR surface,
|
||||
VulkanSurfaceInfo* info);
|
||||
}} // namespace dawn_native::vulkan
|
||||
|
||||
#endif // DAWNNATIVE_VULKAN_VULKANINFO_H_
|
||||
|
Loading…
x
Reference in New Issue
Block a user