[Vulkan] Remove old Vulkan code, change shaders directory, create empty Vulkan backend
This commit is contained in:
@@ -1,540 +0,0 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2020 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include "xenia/ui/vulkan/vulkan_instance.h"
|
||||
|
||||
#include <cinttypes>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
|
||||
#include "third_party/renderdoc/renderdoc_app.h"
|
||||
#include "third_party/volk/volk.h"
|
||||
|
||||
#include "xenia/base/assert.h"
|
||||
#include "xenia/base/logging.h"
|
||||
#include "xenia/base/math.h"
|
||||
#include "xenia/base/profiling.h"
|
||||
#include "xenia/ui/vulkan/vulkan.h"
|
||||
#include "xenia/ui/vulkan/vulkan_immediate_drawer.h"
|
||||
#include "xenia/ui/vulkan/vulkan_util.h"
|
||||
#include "xenia/ui/window.h"
|
||||
|
||||
#if XE_PLATFORM_LINUX
|
||||
#include "xenia/ui/window_gtk.h"
|
||||
#endif
|
||||
|
||||
#define VK_API_VERSION VK_API_VERSION_1_1
|
||||
|
||||
namespace xe {
|
||||
namespace ui {
|
||||
namespace vulkan {
|
||||
|
||||
VulkanInstance::VulkanInstance() {
|
||||
if (cvars::vulkan_validation) {
|
||||
DeclareRequiredLayer("VK_LAYER_LUNARG_standard_validation",
|
||||
Version::Make(0, 0, 0), true);
|
||||
// DeclareRequiredLayer("VK_LAYER_GOOGLE_unique_objects", Version::Make(0,
|
||||
// 0, 0), true);
|
||||
/*
|
||||
DeclareRequiredLayer("VK_LAYER_GOOGLE_threading", Version::Make(0, 0, 0),
|
||||
true);
|
||||
DeclareRequiredLayer("VK_LAYER_LUNARG_core_validation",
|
||||
Version::Make(0, 0, 0), true);
|
||||
DeclareRequiredLayer("VK_LAYER_LUNARG_object_tracker",
|
||||
Version::Make(0, 0, 0), true);
|
||||
DeclareRequiredLayer("VK_LAYER_LUNARG_draw_state", Version::Make(0, 0, 0),
|
||||
true);
|
||||
DeclareRequiredLayer("VK_LAYER_LUNARG_parameter_validation",
|
||||
Version::Make(0, 0, 0), true);
|
||||
DeclareRequiredLayer("VK_LAYER_LUNARG_swapchain", Version::Make(0, 0, 0),
|
||||
true);
|
||||
DeclareRequiredLayer("VK_LAYER_LUNARG_device_limits",
|
||||
Version::Make(0, 0, 0), true);
|
||||
DeclareRequiredLayer("VK_LAYER_LUNARG_image", Version::Make(0, 0, 0), true);
|
||||
*/
|
||||
DeclareRequiredExtension(VK_EXT_DEBUG_REPORT_EXTENSION_NAME,
|
||||
Version::Make(0, 0, 0), true);
|
||||
}
|
||||
|
||||
DeclareRequiredExtension(VK_EXT_DEBUG_MARKER_EXTENSION_NAME,
|
||||
Version::Make(0, 0, 0), true);
|
||||
}
|
||||
|
||||
VulkanInstance::~VulkanInstance() { DestroyInstance(); }
|
||||
|
||||
bool VulkanInstance::Initialize() {
|
||||
auto version = Version::Parse(VK_API_VERSION);
|
||||
XELOGVK("Initializing Vulkan {}...", version.pretty_string);
|
||||
if (volkInitialize() != VK_SUCCESS) {
|
||||
XELOGE("volkInitialize() failed!");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get all of the global layers and extensions provided by the system.
|
||||
if (!QueryGlobals()) {
|
||||
XELOGE("Failed to query instance globals");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Create the vulkan instance used by the application with our required
|
||||
// extensions and layers.
|
||||
if (!CreateInstance()) {
|
||||
XELOGE("Failed to create instance");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Query available devices so that we can pick one.
|
||||
if (!QueryDevices()) {
|
||||
XELOGE("Failed to query devices");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Hook into renderdoc, if it's available.
|
||||
EnableRenderDoc();
|
||||
|
||||
XELOGVK("Instance initialized successfully!");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool VulkanInstance::EnableRenderDoc() {
|
||||
// RenderDoc injects itself into our process, so we should be able to get it.
|
||||
pRENDERDOC_GetAPI get_api = nullptr;
|
||||
#if XE_PLATFORM_WIN32
|
||||
auto module_handle = GetModuleHandleW(L"renderdoc.dll");
|
||||
if (!module_handle) {
|
||||
XELOGI("RenderDoc support requested but it is not attached");
|
||||
return false;
|
||||
}
|
||||
get_api = reinterpret_cast<pRENDERDOC_GetAPI>(
|
||||
GetProcAddress(module_handle, "RENDERDOC_GetAPI"));
|
||||
#else
|
||||
// TODO(benvanik): dlsym/etc - abstracted in base/.
|
||||
#endif // XE_PLATFORM_32
|
||||
if (!get_api) {
|
||||
XELOGI("RenderDoc support requested but it is not attached");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Request all API function pointers.
|
||||
if (!get_api(eRENDERDOC_API_Version_1_0_1,
|
||||
reinterpret_cast<void**>(&renderdoc_api_))) {
|
||||
XELOGE("RenderDoc found but was unable to get API - version mismatch?");
|
||||
return false;
|
||||
}
|
||||
auto api = reinterpret_cast<RENDERDOC_API_1_0_1*>(renderdoc_api_);
|
||||
|
||||
// Query version.
|
||||
int major;
|
||||
int minor;
|
||||
int patch;
|
||||
api->GetAPIVersion(&major, &minor, &patch);
|
||||
XELOGI("RenderDoc attached; {}.{}.{}", major, minor, patch);
|
||||
|
||||
is_renderdoc_attached_ = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool VulkanInstance::QueryGlobals() {
|
||||
// Scan global layers and accumulate properties.
|
||||
// We do this in a loop so that we can allocate the required amount of
|
||||
// memory and handle race conditions while querying.
|
||||
uint32_t count = 0;
|
||||
std::vector<VkLayerProperties> global_layer_properties;
|
||||
VkResult err;
|
||||
do {
|
||||
err = vkEnumerateInstanceLayerProperties(&count, nullptr);
|
||||
CheckResult(err, "vkEnumerateInstanceLayerProperties");
|
||||
global_layer_properties.resize(count);
|
||||
err = vkEnumerateInstanceLayerProperties(&count,
|
||||
global_layer_properties.data());
|
||||
} while (err == VK_INCOMPLETE);
|
||||
CheckResult(err, "vkEnumerateInstanceLayerProperties");
|
||||
global_layers_.resize(count);
|
||||
for (size_t i = 0; i < global_layers_.size(); ++i) {
|
||||
auto& global_layer = global_layers_[i];
|
||||
global_layer.properties = global_layer_properties[i];
|
||||
|
||||
// Get all extensions available for the layer.
|
||||
do {
|
||||
err = vkEnumerateInstanceExtensionProperties(
|
||||
global_layer.properties.layerName, &count, nullptr);
|
||||
CheckResult(err, "vkEnumerateInstanceExtensionProperties");
|
||||
global_layer.extensions.resize(count);
|
||||
err = vkEnumerateInstanceExtensionProperties(
|
||||
global_layer.properties.layerName, &count,
|
||||
global_layer.extensions.data());
|
||||
} while (err == VK_INCOMPLETE);
|
||||
CheckResult(err, "vkEnumerateInstanceExtensionProperties");
|
||||
}
|
||||
XELOGVK("Found {} global layers:", global_layers_.size());
|
||||
for (size_t i = 0; i < global_layers_.size(); ++i) {
|
||||
auto& global_layer = global_layers_[i];
|
||||
auto spec_version = Version::Parse(global_layer.properties.specVersion);
|
||||
auto impl_version =
|
||||
Version::Parse(global_layer.properties.implementationVersion);
|
||||
XELOGVK("- {} (spec: {}, impl: {})", global_layer.properties.layerName,
|
||||
spec_version.pretty_string, impl_version.pretty_string);
|
||||
XELOGVK(" {}", global_layer.properties.description);
|
||||
if (!global_layer.extensions.empty()) {
|
||||
XELOGVK(" {} extensions:", global_layer.extensions.size());
|
||||
DumpExtensions(global_layer.extensions, " ");
|
||||
}
|
||||
}
|
||||
|
||||
// Scan global extensions.
|
||||
do {
|
||||
err = vkEnumerateInstanceExtensionProperties(nullptr, &count, nullptr);
|
||||
CheckResult(err, "vkEnumerateInstanceExtensionProperties");
|
||||
global_extensions_.resize(count);
|
||||
err = vkEnumerateInstanceExtensionProperties(nullptr, &count,
|
||||
global_extensions_.data());
|
||||
} while (err == VK_INCOMPLETE);
|
||||
CheckResult(err, "vkEnumerateInstanceExtensionProperties");
|
||||
XELOGVK("Found {} global extensions:", global_extensions_.size());
|
||||
DumpExtensions(global_extensions_, "");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool VulkanInstance::CreateInstance() {
|
||||
XELOGVK("Verifying layers and extensions...");
|
||||
|
||||
// Gather list of enabled layer names.
|
||||
auto layers_result = CheckRequirements(required_layers_, global_layers_);
|
||||
auto& enabled_layers = layers_result.second;
|
||||
|
||||
// Gather list of enabled extension names.
|
||||
auto extensions_result =
|
||||
CheckRequirements(required_extensions_, global_extensions_);
|
||||
auto& enabled_extensions = extensions_result.second;
|
||||
|
||||
// We wait until both extensions and layers are checked before failing out so
|
||||
// that the user gets a complete list of what they have/don't.
|
||||
if (!extensions_result.first || !layers_result.first) {
|
||||
XELOGE("Layer and extension verification failed; aborting initialization");
|
||||
return false;
|
||||
}
|
||||
|
||||
XELOGVK("Initializing application instance...");
|
||||
|
||||
// TODO(benvanik): use GetEntryInfo?
|
||||
VkApplicationInfo application_info;
|
||||
application_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
|
||||
application_info.pNext = nullptr;
|
||||
application_info.pApplicationName = "xenia";
|
||||
application_info.applicationVersion = 1;
|
||||
application_info.pEngineName = "xenia";
|
||||
application_info.engineVersion = 1;
|
||||
application_info.apiVersion = VK_API_VERSION;
|
||||
|
||||
VkInstanceCreateInfo instance_info;
|
||||
instance_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
|
||||
instance_info.pNext = nullptr;
|
||||
instance_info.flags = 0;
|
||||
instance_info.pApplicationInfo = &application_info;
|
||||
instance_info.enabledLayerCount =
|
||||
static_cast<uint32_t>(enabled_layers.size());
|
||||
instance_info.ppEnabledLayerNames = enabled_layers.data();
|
||||
instance_info.enabledExtensionCount =
|
||||
static_cast<uint32_t>(enabled_extensions.size());
|
||||
instance_info.ppEnabledExtensionNames = enabled_extensions.data();
|
||||
|
||||
auto err = vkCreateInstance(&instance_info, nullptr, &handle);
|
||||
if (err != VK_SUCCESS) {
|
||||
XELOGE("vkCreateInstance returned {}", to_string(err));
|
||||
}
|
||||
switch (err) {
|
||||
case VK_SUCCESS:
|
||||
// Ok!
|
||||
break;
|
||||
case VK_ERROR_INITIALIZATION_FAILED:
|
||||
XELOGE("Instance initialization failed; generic");
|
||||
return false;
|
||||
case VK_ERROR_INCOMPATIBLE_DRIVER:
|
||||
XELOGE(
|
||||
"Instance initialization failed; cannot find a compatible Vulkan "
|
||||
"installable client driver (ICD)");
|
||||
return false;
|
||||
case VK_ERROR_EXTENSION_NOT_PRESENT:
|
||||
XELOGE("Instance initialization failed; requested extension not present");
|
||||
return false;
|
||||
case VK_ERROR_LAYER_NOT_PRESENT:
|
||||
XELOGE("Instance initialization failed; requested layer not present");
|
||||
return false;
|
||||
default:
|
||||
XELOGE("Instance initialization failed; unknown: {}", to_string(err));
|
||||
return false;
|
||||
}
|
||||
|
||||
// Load Vulkan entrypoints and extensions.
|
||||
volkLoadInstance(handle);
|
||||
|
||||
// Enable debug validation, if needed.
|
||||
EnableDebugValidation();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void VulkanInstance::DestroyInstance() {
|
||||
if (!handle) {
|
||||
return;
|
||||
}
|
||||
DisableDebugValidation();
|
||||
vkDestroyInstance(handle, nullptr);
|
||||
handle = nullptr;
|
||||
}
|
||||
|
||||
VkBool32 VKAPI_PTR DebugMessageCallback(VkDebugReportFlagsEXT flags,
|
||||
VkDebugReportObjectTypeEXT objectType,
|
||||
uint64_t object, size_t location,
|
||||
int32_t messageCode,
|
||||
const char* pLayerPrefix,
|
||||
const char* pMessage, void* pUserData) {
|
||||
if (strcmp(pLayerPrefix, "Validation") == 0) {
|
||||
const char* blacklist[] = {
|
||||
"bound but it was never updated. You may want to either update it or "
|
||||
"not bind it.",
|
||||
"is being used in draw but has not been updated.",
|
||||
};
|
||||
for (uint32_t i = 0; i < xe::countof(blacklist); ++i) {
|
||||
if (strstr(pMessage, blacklist[i]) != nullptr) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto instance = reinterpret_cast<VulkanInstance*>(pUserData);
|
||||
const char* message_type = "UNKNOWN";
|
||||
if (flags & VK_DEBUG_REPORT_ERROR_BIT_EXT) {
|
||||
message_type = "ERROR";
|
||||
} else if (flags & VK_DEBUG_REPORT_WARNING_BIT_EXT) {
|
||||
message_type = "WARN";
|
||||
} else if (flags & VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT) {
|
||||
message_type = "PERF WARN";
|
||||
} else if (flags & VK_DEBUG_REPORT_INFORMATION_BIT_EXT) {
|
||||
message_type = "INFO";
|
||||
} else if (flags & VK_DEBUG_REPORT_DEBUG_BIT_EXT) {
|
||||
message_type = "DEBUG";
|
||||
}
|
||||
|
||||
XELOGVK("[{}/{}:{}] {}", pLayerPrefix, message_type, messageCode, pMessage);
|
||||
return false;
|
||||
}
|
||||
|
||||
void VulkanInstance::EnableDebugValidation() {
|
||||
if (dbg_report_callback_) {
|
||||
DisableDebugValidation();
|
||||
}
|
||||
auto vk_create_debug_report_callback_ext =
|
||||
reinterpret_cast<PFN_vkCreateDebugReportCallbackEXT>(
|
||||
vkGetInstanceProcAddr(handle, "vkCreateDebugReportCallbackEXT"));
|
||||
if (!vk_create_debug_report_callback_ext) {
|
||||
XELOGVK("Debug validation layer not installed; ignoring");
|
||||
return;
|
||||
}
|
||||
VkDebugReportCallbackCreateInfoEXT create_info;
|
||||
create_info.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT;
|
||||
create_info.pNext = nullptr;
|
||||
// TODO(benvanik): flags to set these.
|
||||
create_info.flags =
|
||||
VK_DEBUG_REPORT_INFORMATION_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT |
|
||||
VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT |
|
||||
VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_DEBUG_BIT_EXT;
|
||||
create_info.pfnCallback = &DebugMessageCallback;
|
||||
create_info.pUserData = this;
|
||||
auto status = vk_create_debug_report_callback_ext(
|
||||
handle, &create_info, nullptr, &dbg_report_callback_);
|
||||
if (status == VK_SUCCESS) {
|
||||
XELOGVK("Debug validation layer enabled");
|
||||
} else {
|
||||
XELOGVK("Debug validation layer failed to install; error {}",
|
||||
to_string(status));
|
||||
}
|
||||
}
|
||||
|
||||
void VulkanInstance::DisableDebugValidation() {
|
||||
if (!dbg_report_callback_) {
|
||||
return;
|
||||
}
|
||||
auto vk_destroy_debug_report_callback_ext =
|
||||
reinterpret_cast<PFN_vkDestroyDebugReportCallbackEXT>(
|
||||
vkGetInstanceProcAddr(handle, "vkDestroyDebugReportCallbackEXT"));
|
||||
if (!vk_destroy_debug_report_callback_ext) {
|
||||
return;
|
||||
}
|
||||
vk_destroy_debug_report_callback_ext(handle, dbg_report_callback_, nullptr);
|
||||
dbg_report_callback_ = nullptr;
|
||||
}
|
||||
|
||||
bool VulkanInstance::QueryDevices() {
|
||||
// Get handles to all devices.
|
||||
uint32_t count = 0;
|
||||
std::vector<VkPhysicalDevice> device_handles;
|
||||
auto err = vkEnumeratePhysicalDevices(handle, &count, nullptr);
|
||||
CheckResult(err, "vkEnumeratePhysicalDevices");
|
||||
|
||||
device_handles.resize(count);
|
||||
err = vkEnumeratePhysicalDevices(handle, &count, device_handles.data());
|
||||
CheckResult(err, "vkEnumeratePhysicalDevices");
|
||||
|
||||
// Query device info.
|
||||
for (size_t i = 0; i < device_handles.size(); ++i) {
|
||||
auto device_handle = device_handles[i];
|
||||
DeviceInfo device_info;
|
||||
device_info.handle = device_handle;
|
||||
|
||||
// Query general attributes.
|
||||
vkGetPhysicalDeviceProperties(device_handle, &device_info.properties);
|
||||
vkGetPhysicalDeviceFeatures(device_handle, &device_info.features);
|
||||
vkGetPhysicalDeviceMemoryProperties(device_handle,
|
||||
&device_info.memory_properties);
|
||||
|
||||
// Gather queue family properties.
|
||||
vkGetPhysicalDeviceQueueFamilyProperties(device_handle, &count, nullptr);
|
||||
device_info.queue_family_properties.resize(count);
|
||||
vkGetPhysicalDeviceQueueFamilyProperties(
|
||||
device_handle, &count, device_info.queue_family_properties.data());
|
||||
|
||||
// Gather layers.
|
||||
std::vector<VkLayerProperties> layer_properties;
|
||||
err = vkEnumerateDeviceLayerProperties(device_handle, &count, nullptr);
|
||||
CheckResult(err, "vkEnumerateDeviceLayerProperties");
|
||||
layer_properties.resize(count);
|
||||
err = vkEnumerateDeviceLayerProperties(device_handle, &count,
|
||||
layer_properties.data());
|
||||
CheckResult(err, "vkEnumerateDeviceLayerProperties");
|
||||
for (size_t j = 0; j < layer_properties.size(); ++j) {
|
||||
LayerInfo layer_info;
|
||||
layer_info.properties = layer_properties[j];
|
||||
err = vkEnumerateDeviceExtensionProperties(
|
||||
device_handle, layer_info.properties.layerName, &count, nullptr);
|
||||
CheckResult(err, "vkEnumerateDeviceExtensionProperties");
|
||||
layer_info.extensions.resize(count);
|
||||
err = vkEnumerateDeviceExtensionProperties(
|
||||
device_handle, layer_info.properties.layerName, &count,
|
||||
layer_info.extensions.data());
|
||||
CheckResult(err, "vkEnumerateDeviceExtensionProperties");
|
||||
device_info.layers.push_back(std::move(layer_info));
|
||||
}
|
||||
|
||||
// Gather extensions.
|
||||
err = vkEnumerateDeviceExtensionProperties(device_handle, nullptr, &count,
|
||||
nullptr);
|
||||
CheckResult(err, "vkEnumerateDeviceExtensionProperties");
|
||||
device_info.extensions.resize(count);
|
||||
err = vkEnumerateDeviceExtensionProperties(device_handle, nullptr, &count,
|
||||
device_info.extensions.data());
|
||||
CheckResult(err, "vkEnumerateDeviceExtensionProperties");
|
||||
|
||||
available_devices_.push_back(std::move(device_info));
|
||||
}
|
||||
|
||||
XELOGVK("Found {} physical devices:", available_devices_.size());
|
||||
for (size_t i = 0; i < available_devices_.size(); ++i) {
|
||||
auto& device_info = available_devices_[i];
|
||||
XELOGVK("- Device {}:", i);
|
||||
DumpDeviceInfo(device_info);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void VulkanInstance::DumpLayers(const std::vector<LayerInfo>& layers,
|
||||
const char* indent) {
|
||||
for (size_t i = 0; i < layers.size(); ++i) {
|
||||
auto& layer = layers[i];
|
||||
auto spec_version = Version::Parse(layer.properties.specVersion);
|
||||
auto impl_version = Version::Parse(layer.properties.implementationVersion);
|
||||
XELOGVK("{}- {} (spec: {}, impl: {})", indent, layer.properties.layerName,
|
||||
spec_version.pretty_string, impl_version.pretty_string);
|
||||
XELOGVK("{} {}", indent, layer.properties.description);
|
||||
if (!layer.extensions.empty()) {
|
||||
XELOGVK("{} {} extensions:", indent, layer.extensions.size());
|
||||
DumpExtensions(layer.extensions, std::strlen(indent) ? " " : " ");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VulkanInstance::DumpExtensions(
|
||||
const std::vector<VkExtensionProperties>& extensions, const char* indent) {
|
||||
for (size_t i = 0; i < extensions.size(); ++i) {
|
||||
auto& extension = extensions[i];
|
||||
auto version = Version::Parse(extension.specVersion);
|
||||
XELOGVK("{}- {} ({})", indent, extension.extensionName,
|
||||
version.pretty_string);
|
||||
}
|
||||
}
|
||||
|
||||
void VulkanInstance::DumpDeviceInfo(const DeviceInfo& device_info) {
|
||||
auto& properties = device_info.properties;
|
||||
auto api_version = Version::Parse(properties.apiVersion);
|
||||
auto driver_version = Version::Parse(properties.driverVersion);
|
||||
XELOGVK(" apiVersion = {}", api_version.pretty_string);
|
||||
XELOGVK(" driverVersion = {}", driver_version.pretty_string);
|
||||
XELOGVK(" vendorId = {:#04x}", properties.vendorID);
|
||||
XELOGVK(" deviceId = {:#04x}", properties.deviceID);
|
||||
XELOGVK(" deviceType = {}", to_string(properties.deviceType));
|
||||
XELOGVK(" deviceName = {}", properties.deviceName);
|
||||
|
||||
auto& memory_props = device_info.memory_properties;
|
||||
XELOGVK(" Memory Heaps:");
|
||||
for (size_t j = 0; j < memory_props.memoryHeapCount; ++j) {
|
||||
XELOGVK(" - Heap {}: {} bytes", j, memory_props.memoryHeaps[j].size);
|
||||
for (size_t k = 0; k < memory_props.memoryTypeCount; ++k) {
|
||||
if (memory_props.memoryTypes[k].heapIndex == j) {
|
||||
XELOGVK(" - Type {}:", k);
|
||||
auto type_flags = memory_props.memoryTypes[k].propertyFlags;
|
||||
if (!type_flags) {
|
||||
XELOGVK(" VK_MEMORY_PROPERTY_DEVICE_ONLY");
|
||||
}
|
||||
if (type_flags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) {
|
||||
XELOGVK(" VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT");
|
||||
}
|
||||
if (type_flags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) {
|
||||
XELOGVK(" VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT");
|
||||
}
|
||||
if (type_flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) {
|
||||
XELOGVK(" VK_MEMORY_PROPERTY_HOST_COHERENT_BIT");
|
||||
}
|
||||
if (type_flags & VK_MEMORY_PROPERTY_HOST_CACHED_BIT) {
|
||||
XELOGVK(" VK_MEMORY_PROPERTY_HOST_CACHED_BIT");
|
||||
}
|
||||
if (type_flags & VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT) {
|
||||
XELOGVK(" VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
XELOGVK(" Queue Families:");
|
||||
for (size_t j = 0; j < device_info.queue_family_properties.size(); ++j) {
|
||||
auto& queue_props = device_info.queue_family_properties[j];
|
||||
XELOGVK(" - Queue {}:", j);
|
||||
XELOGVK(
|
||||
" queueFlags = {}{}{}{}",
|
||||
(queue_props.queueFlags & VK_QUEUE_GRAPHICS_BIT) ? "graphics, " : "",
|
||||
(queue_props.queueFlags & VK_QUEUE_COMPUTE_BIT) ? "compute, " : "",
|
||||
(queue_props.queueFlags & VK_QUEUE_TRANSFER_BIT) ? "transfer, " : "",
|
||||
(queue_props.queueFlags & VK_QUEUE_SPARSE_BINDING_BIT) ? "sparse, "
|
||||
: "");
|
||||
XELOGVK(" queueCount = {}", queue_props.queueCount);
|
||||
XELOGVK(" timestampValidBits = {}", queue_props.timestampValidBits);
|
||||
}
|
||||
|
||||
XELOGVK(" Layers:");
|
||||
DumpLayers(device_info.layers, " ");
|
||||
|
||||
XELOGVK(" Extensions:");
|
||||
DumpExtensions(device_info.extensions, " ");
|
||||
}
|
||||
|
||||
} // namespace vulkan
|
||||
} // namespace ui
|
||||
} // namespace xe
|
||||
Reference in New Issue
Block a user